From b8aed7ca867c1b9cc7ae02f7b129082b9c218e7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 25 Oct 2021 12:59:55 +0200 Subject: [PATCH 01/69] Run external tests on latest upstream code where possible --- test/externalTests/ens.sh | 2 +- test/externalTests/zeppelin.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/externalTests/ens.sh b/test/externalTests/ens.sh index a19ce859d..90c96d5a5 100755 --- a/test/externalTests/ens.sh +++ b/test/externalTests/ens.sh @@ -33,7 +33,7 @@ function ens_test export OPTIMIZER_LEVEL=1 export CONFIG="truffle-config.js" - truffle_setup "$SOLJSON" https://github.com/solidity-external-tests/ens.git master_080 + truffle_setup "$SOLJSON" https://github.com/ensdomains/ens.git master # Use latest Truffle. Older versions crash on the output from 0.8.0. force_truffle_version ^5.1.55 diff --git a/test/externalTests/zeppelin.sh b/test/externalTests/zeppelin.sh index 8d8cb4845..97da3d47b 100755 --- a/test/externalTests/zeppelin.sh +++ b/test/externalTests/zeppelin.sh @@ -33,7 +33,7 @@ function zeppelin_test OPTIMIZER_LEVEL=1 CONFIG="truffle-config.js" - truffle_setup "$SOLJSON" https://github.com/solidity-external-tests/openzeppelin-contracts.git master_080 + truffle_setup "$SOLJSON" https://github.com/OpenZeppelin/openzeppelin-contracts.git master run_install "$SOLJSON" install_fn truffle_run_test "$SOLJSON" compile_fn test_fn From 14210825b1fd31c2a1ac6f983d4129c4ec9c8619 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 25 Oct 2021 13:10:15 +0200 Subject: [PATCH 02/69] externalTests/README: Recommend using upstream repository directly when possible --- test/externalTests/README.md | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/test/externalTests/README.md b/test/externalTests/README.md index a6c160846..76e39a79b 100644 --- a/test/externalTests/README.md +++ b/test/externalTests/README.md @@ -13,16 +13,17 @@ these projects *can* be upgraded at all. ### Recommended workflow #### Adding a new external project -1. Create a fork of the upstream repository in https://github.com/solidity-external-tests/. If the - project consists of several repositories, fork them all. -2. Remove all the branches except for main one (`master`, `develop`, `main`, etc). This branch is - going to be always kept up to date with the upstream repository and should not contain any extra - commits. +1. If the upstream code cannot be compiled without modifications, create a fork of the repository + in https://github.com/solidity-external-tests/. +2. In our fork, remove all the branches except for main one (`master`, `develop`, `main`, etc). + This branch is going to be always kept up to date with the upstream repository and should not + contain any extra commits. - If the project is not up to date with the latest compiler version but has a branch that is, try to use that branch instead. -3. Create a new branch named after the main branch and the compiler version from our `develop` - branch. E.g. if the latest Solidity version is 0.7.5 and the main branch of the external project - is called `master`, create `master_070`. This is where we will be adding our own commits. +3. In our fork, create a new branch named after the main branch and the compiler version from our + `develop` branch. + E.g. if the latest Solidity version is 0.7.5 and the main branch of the external project + is called `master`, create `master_070`. This is where we will be adding our own commits. 4. Create a script for compiling/testing the project and put it in `test/externalTests/` in the Solidity repository. - The script should apply workarounds necessary to make the project actually use the compiler @@ -39,12 +40,12 @@ these projects *can* be upgraded at all. and add necessary workarounds there. Continuing the example above, the new branch would be called `master_080` and should be rebased on top of `master_070`. - The fewer commits in these branches, the better. Ideally, any changes needed to make the compiler - work should be submitted upstream and our branches should just be tracking the main upstream - branch without any extra commits. + work should be submitted upstream and our scripts should be using the upstream repository + directly. #### Updating external projects for a PR that introduces breaking changes in the compiler If a PR to our `breaking` branch introduces changes that will make an external project no longer -compile or pass its tests, the fork needs to be modified: +compile or pass its tests, the fork needs to be modified (or created if it does not yet exist): - If a branch specific to the compiler version from `breaking` does not exist yet: 1. Create the branch. It should be based on the version-specific branch used on `develop`. 2. Make your PR modify the project script in `test/externalScripts/` to use the new branch. @@ -84,7 +85,7 @@ to use the updated copies of the branches and can be discarded aferwards without When a non-backwards-compatible version becomes the most recent release, `breaking` branch gets merged into `develop` which automatically results in a switch to the newer version-specific branches if they exist. If no changes on our part were necessary, it is completely fine to keep using -e.g. the `master_060` of an external project in in Solidity 0.8.x. +e.g. the `master_060` of an external project in Solidity 0.8.x. Since each project is handled separately, this approach may result in a mix of version-specific branches between different external projects. For example, in one project we could could have `master_050` on From eb2425bd7c14db2d98ca06a50586ecc8093b0652 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 27 Oct 2021 18:02:26 +0200 Subject: [PATCH 03/69] isoltest: Fix gas tests always being enforced regardless of evm version --- test/tools/IsolTestOptions.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/tools/IsolTestOptions.cpp b/test/tools/IsolTestOptions.cpp index 7f00e88f6..d2323ec16 100644 --- a/test/tools/IsolTestOptions.cpp +++ b/test/tools/IsolTestOptions.cpp @@ -60,7 +60,6 @@ IsolTestOptions::IsolTestOptions(): CommonOptions(description) { enforceViaYul = true; - enforceGasTest = (evmVersion() == langutil::EVMVersion{}); } void IsolTestOptions::addOptions() @@ -84,6 +83,8 @@ bool IsolTestOptions::parse(int _argc, char const* const* _argv) return false; } + enforceGasTest = enforceGasTest || (evmVersion() == langutil::EVMVersion{}); + return res; } From a0394316274b9811be7d3c98c0ce687dfcb10e59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 27 Oct 2021 18:20:04 +0200 Subject: [PATCH 04/69] isoltest: Do not try to enforce gas costs when ABIEncoderV1 is used --- test/tools/IsolTestOptions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/tools/IsolTestOptions.cpp b/test/tools/IsolTestOptions.cpp index d2323ec16..cdd1b85ab 100644 --- a/test/tools/IsolTestOptions.cpp +++ b/test/tools/IsolTestOptions.cpp @@ -83,7 +83,7 @@ bool IsolTestOptions::parse(int _argc, char const* const* _argv) return false; } - enforceGasTest = enforceGasTest || (evmVersion() == langutil::EVMVersion{}); + enforceGasTest = enforceGasTest || (evmVersion() == langutil::EVMVersion{} && !useABIEncoderV1); return res; } From f4421f1b695ce4798927f30896743408319eddb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 27 Oct 2021 19:52:36 +0200 Subject: [PATCH 05/69] Disable metadata in syntax tests --- test/libsolidity/SyntaxTest.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/libsolidity/SyntaxTest.cpp b/test/libsolidity/SyntaxTest.cpp index 2a70c35ab..4998b628b 100644 --- a/test/libsolidity/SyntaxTest.cpp +++ b/test/libsolidity/SyntaxTest.cpp @@ -77,6 +77,8 @@ void SyntaxTest::setupCompiler() OptimiserSettings::full() : OptimiserSettings::minimal() ); + compiler().setMetadataFormat(CompilerStack::MetadataFormat::NoMetadata); + compiler().setMetadataHash(CompilerStack::MetadataHash::None); } void SyntaxTest::parseAndAnalyze() From 79ffa16a61dc866f500551ab2213ad2387f38d9c Mon Sep 17 00:00:00 2001 From: David Dzhalaev <72649244+DavidRomanovizc@users.noreply.github.com> Date: Fri, 22 Oct 2021 00:41:22 +0300 Subject: [PATCH 06/69] Improve error message for contract size limit error --- libsolidity/interface/CompilerStack.cpp | 5 ++++- test/libsolidity/syntaxTests/bytecode_too_large.sol | 6 ++++-- .../syntaxTests/bytecode_too_large_abiencoder_v1.sol | 12 ++++++++++++ .../syntaxTests/bytecode_too_large_byzantium.sol | 10 ++++++++++ .../syntaxTests/bytecode_too_large_homestead.sol | 9 +++++++++ 5 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 test/libsolidity/syntaxTests/bytecode_too_large_abiencoder_v1.sol create mode 100644 test/libsolidity/syntaxTests/bytecode_too_large_byzantium.sol create mode 100644 test/libsolidity/syntaxTests/bytecode_too_large_homestead.sol diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 9fa3cb164..9ec3a402e 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -83,6 +83,7 @@ #include #include #include +#include using namespace std; using namespace solidity; @@ -1248,7 +1249,9 @@ void CompilerStack::assemble( m_errorReporter.warning( 5574_error, _contract.location(), - "Contract code size exceeds 24576 bytes (a limit introduced in Spurious Dragon). " + "Contract code size is "s + + to_string(compiledContract.runtimeObject.bytecode.size()) + + " 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." diff --git a/test/libsolidity/syntaxTests/bytecode_too_large.sol b/test/libsolidity/syntaxTests/bytecode_too_large.sol index 58446e0da..55d637bfb 100644 --- a/test/libsolidity/syntaxTests/bytecode_too_large.sol +++ b/test/libsolidity/syntaxTests/bytecode_too_large.sol @@ -1,3 +1,5 @@ +pragma abicoder v2; + contract test { function f() public pure returns (string memory ret) { // 27000 bytes long data @@ -5,6 +7,6 @@ contract test { } } // ==== -// EVMVersion: >=spuriousDragon +// EVMVersion: >byzantium // ---- -// Warning 5574: (0-27133): Contract code size 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. +// Warning 5574: (21-27154): Contract code size is 27199 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. diff --git a/test/libsolidity/syntaxTests/bytecode_too_large_abiencoder_v1.sol b/test/libsolidity/syntaxTests/bytecode_too_large_abiencoder_v1.sol new file mode 100644 index 000000000..69dc7ebd0 --- /dev/null +++ b/test/libsolidity/syntaxTests/bytecode_too_large_abiencoder_v1.sol @@ -0,0 +1,12 @@ +pragma abicoder v1; + +contract test { + function f() public pure returns (string memory ret) { + // 27000 bytes long data + ret = "........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................"; + } +} +// ==== +// EVMVersion: >byzantium +// ---- +// Warning 5574: (21-27154): Contract code size is 27209 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. diff --git a/test/libsolidity/syntaxTests/bytecode_too_large_byzantium.sol b/test/libsolidity/syntaxTests/bytecode_too_large_byzantium.sol new file mode 100644 index 000000000..a95ed192a --- /dev/null +++ b/test/libsolidity/syntaxTests/bytecode_too_large_byzantium.sol @@ -0,0 +1,10 @@ +contract test { + function f() public pure returns (string memory ret) { + // 27000 bytes long data + ret = "........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................"; + } +} +// ==== +// EVMVersion: =byzantium +// ---- +// Warning 5574: (0-27133): Contract code size is 27227 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. diff --git a/test/libsolidity/syntaxTests/bytecode_too_large_homestead.sol b/test/libsolidity/syntaxTests/bytecode_too_large_homestead.sol new file mode 100644 index 000000000..946f5e8b4 --- /dev/null +++ b/test/libsolidity/syntaxTests/bytecode_too_large_homestead.sol @@ -0,0 +1,9 @@ +contract test { + function f() public pure returns (string memory ret) { + // 27000 bytes long data + ret = "........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................"; + } +} +// ==== +// EVMVersion: =homestead +// ---- From 464ac18a1f451430d1e2e7f1090a2671237e27d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 28 Oct 2021 16:39:51 +0200 Subject: [PATCH 07/69] Rename negation_bug.yul to negation_bug.sol --- .../semanticTests/viaYul/{negation_bug.yul => negation_bug.sol} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/libsolidity/semanticTests/viaYul/{negation_bug.yul => negation_bug.sol} (100%) diff --git a/test/libsolidity/semanticTests/viaYul/negation_bug.yul b/test/libsolidity/semanticTests/viaYul/negation_bug.sol similarity index 100% rename from test/libsolidity/semanticTests/viaYul/negation_bug.yul rename to test/libsolidity/semanticTests/viaYul/negation_bug.sol From 60ba3b307fd5e16cd0f68f0533e982a66ce5877b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 28 Oct 2021 17:34:57 +0200 Subject: [PATCH 08/69] isolate_tests: Fix typo in script description --- scripts/isolate_tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/isolate_tests.py b/scripts/isolate_tests.py index 1e2170e82..4abe6a0bd 100755 --- a/scripts/isolate_tests.py +++ b/scripts/isolate_tests.py @@ -134,7 +134,7 @@ def extract_and_write(path, language): if __name__ == '__main__': script_description = ( "Reads Solidity, C++ or RST source files and extracts compilable solidity and yul code blocks from them. " - "Can be used to generate test cases to validade code examples. " + "Can be used to generate test cases to validate code examples. " ) parser = ArgumentParser(description=script_description) From fd66f13dc0ca8052eb3bf1dedf5afb6ed8c14399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 28 Oct 2021 19:08:06 +0200 Subject: [PATCH 09/69] soltest.sh: Fix typo in a comment --- .circleci/soltest.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/soltest.sh b/.circleci/soltest.sh index 4f9bd8a81..1814b8728 100755 --- a/.circleci/soltest.sh +++ b/.circleci/soltest.sh @@ -46,7 +46,7 @@ source "${REPODIR}/scripts/common.sh" # Test result output directory (CircleCI is reading test results from here) mkdir -p test_results -# in case we run with ASAN enabled, we must increase stck size. +# in case we run with ASAN enabled, we must increase stack size. ulimit -s 16384 get_logfile_basename() { From 8e208f23cba81f965b178a076de2e2f4c144a70d Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 28 Oct 2021 16:25:43 +0200 Subject: [PATCH 10/69] Fix assignment of return variables from modifiers. --- Changelog.md | 3 +++ libsolidity/codegen/ir/IRGenerator.cpp | 4 ++-- .../function_modifier_return_reference.sol | 15 +++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 test/libsolidity/semanticTests/modifiers/function_modifier_return_reference.sol diff --git a/Changelog.md b/Changelog.md index ff183e22b..4cfbe6637 100644 --- a/Changelog.md +++ b/Changelog.md @@ -29,6 +29,9 @@ Bugfixes: * Yul IR Generator: Do not output empty switches/if-bodies for empty contracts. +Important Bugfixes in Experimental Features: + * 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. + ### 0.8.9 (2021-09-29) diff --git a/libsolidity/codegen/ir/IRGenerator.cpp b/libsolidity/codegen/ir/IRGenerator.cpp index 44cd534ff..b17b33c03 100644 --- a/libsolidity/codegen/ir/IRGenerator.cpp +++ b/libsolidity/codegen/ir/IRGenerator.cpp @@ -438,7 +438,7 @@ string IRGenerator::generateModifier( for (size_t i = 0; i < retParamsIn.size(); ++i) { retParams.emplace_back(m_context.newYulVariable()); - assignRetParams += retParams.back() + " := " + retParamsIn[i] + "\n"; + assignRetParams += retParams.at(i) + " := " + retParamsIn.at(i) + "\n"; } t("retParams", joinHumanReadable(retParams)); t("assignRetParams", assignRetParams); @@ -529,7 +529,7 @@ string IRGenerator::generateFunctionWithModifierInner(FunctionDefinition const& for (size_t i = 0; i < retParams.size(); ++i) { retParamsIn.emplace_back(m_context.newYulVariable()); - assignRetParams += retParams.back() + " := " + retParamsIn[i] + "\n"; + assignRetParams += retParams.at(i) + " := " + retParamsIn.at(i) + "\n"; } vector params = retParamsIn; for (auto const& varDecl: _function.parameters()) diff --git a/test/libsolidity/semanticTests/modifiers/function_modifier_return_reference.sol b/test/libsolidity/semanticTests/modifiers/function_modifier_return_reference.sol new file mode 100644 index 000000000..1da6c011d --- /dev/null +++ b/test/libsolidity/semanticTests/modifiers/function_modifier_return_reference.sol @@ -0,0 +1,15 @@ +contract C { + modifier m1(uint value) { + _; + } + modifier m2(uint value) { + _; + } + + function f() public m1(x = 2) m2(y = 3) returns (uint x, uint y) { + } +} +// ==== +// compileViaYul: also +// ---- +// f() -> 2, 3 From 7683442ce27c083c5f51484ba9322c0678339406 Mon Sep 17 00:00:00 2001 From: hrkrshnn Date: Mon, 1 Nov 2021 10:24:08 +0100 Subject: [PATCH 11/69] Semantic test for high level call to precompiles. Because of the extcodesize check, the high level call will fail. Even though the low level call can succeed and return data. --- .../precompile_extcodesize_check.sol | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 test/libsolidity/semanticTests/functionCall/precompile_extcodesize_check.sol diff --git a/test/libsolidity/semanticTests/functionCall/precompile_extcodesize_check.sol b/test/libsolidity/semanticTests/functionCall/precompile_extcodesize_check.sol new file mode 100644 index 000000000..7a9025e26 --- /dev/null +++ b/test/libsolidity/semanticTests/functionCall/precompile_extcodesize_check.sol @@ -0,0 +1,25 @@ +interface Identity { + function selectorAndAppendValue(uint value) external pure returns (uint); +} +contract C { + Identity constant i = Identity(address(0x0004)); + function testHighLevel() external pure returns (bool) { + // Should fail because `extcodesize(4) = 0` + i.selectorAndAppendValue(5); + return true; + } + function testLowLevel() external view returns (uint value) { + (bool success, bytes memory ret) = + address(4).staticcall( + abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5)) + ); + value = abi.decode(ret, (uint)); + } + +} +// ==== +// compileViaYul: also +// EVMVersion: >=constantinople +// ---- +// testHighLevel() -> FAILURE +// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000 From d6c461ed618849fcad037974455d65aa4e09c9e0 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 5 Oct 2021 18:46:49 +0200 Subject: [PATCH 12/69] Use side effects of user-defined functions in other optimizer steps. --- libyul/optimiser/ConditionalSimplifier.cpp | 9 +++++- libyul/optimiser/ConditionalSimplifier.h | 14 +++++----- libyul/optimiser/ConditionalUnsimplifier.cpp | 9 +++++- libyul/optimiser/ConditionalUnsimplifier.h | 13 +++++---- libyul/optimiser/DeadCodeEliminator.cpp | 9 ++++-- libyul/optimiser/DeadCodeEliminator.h | 11 ++++++-- libyul/optimiser/Semantics.cpp | 29 ++++++++++++++++---- libyul/optimiser/Semantics.h | 26 ++++++++++++------ 8 files changed, 88 insertions(+), 32 deletions(-) diff --git a/libyul/optimiser/ConditionalSimplifier.cpp b/libyul/optimiser/ConditionalSimplifier.cpp index ea32949ed..3a2e8aa4e 100644 --- a/libyul/optimiser/ConditionalSimplifier.cpp +++ b/libyul/optimiser/ConditionalSimplifier.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include using namespace std; @@ -26,6 +27,12 @@ using namespace solidity; using namespace solidity::yul; using namespace solidity::util; +void ConditionalSimplifier::run(OptimiserStepContext& _context, Block& _ast) +{ + ControlFlowSideEffectsCollector sideEffects(_context.dialect, _ast); + ConditionalSimplifier{_context.dialect, sideEffects.functionSideEffects()}(_ast); +} + void ConditionalSimplifier::operator()(Switch& _switch) { visit(*_switch.expression); @@ -65,7 +72,7 @@ void ConditionalSimplifier::operator()(Block& _block) if ( holds_alternative(*_if.condition) && !_if.body.statements.empty() && - TerminationFinder(m_dialect).controlFlowKind(_if.body.statements.back()) != + TerminationFinder(m_dialect, &m_functionSideEffects).controlFlowKind(_if.body.statements.back()) != TerminationFinder::ControlFlow::FlowOut ) { diff --git a/libyul/optimiser/ConditionalSimplifier.h b/libyul/optimiser/ConditionalSimplifier.h index e41ee579c..57a6696c4 100644 --- a/libyul/optimiser/ConditionalSimplifier.h +++ b/libyul/optimiser/ConditionalSimplifier.h @@ -44,7 +44,6 @@ namespace solidity::yul * * Future features: * - allow replacements by "1" - * - take termination of user-defined functions into account * * Works best with SSA form and if dead code removal has run before. * @@ -54,20 +53,21 @@ class ConditionalSimplifier: public ASTModifier { public: static constexpr char const* name{"ConditionalSimplifier"}; - static void run(OptimiserStepContext& _context, Block& _ast) - { - ConditionalSimplifier{_context.dialect}(_ast); - } + static void run(OptimiserStepContext& _context, Block& _ast); using ASTModifier::operator(); void operator()(Switch& _switch) override; void operator()(Block& _block) override; private: - explicit ConditionalSimplifier(Dialect const& _dialect): - m_dialect(_dialect) + explicit ConditionalSimplifier( + Dialect const& _dialect, + std::map const& _sideEffects + ): + m_dialect(_dialect), m_functionSideEffects(_sideEffects) {} Dialect const& m_dialect; + std::map const& m_functionSideEffects; }; } diff --git a/libyul/optimiser/ConditionalUnsimplifier.cpp b/libyul/optimiser/ConditionalUnsimplifier.cpp index f522654d4..752e06918 100644 --- a/libyul/optimiser/ConditionalUnsimplifier.cpp +++ b/libyul/optimiser/ConditionalUnsimplifier.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include using namespace std; @@ -27,6 +28,12 @@ using namespace solidity; using namespace solidity::yul; using namespace solidity::util; +void ConditionalUnsimplifier::run(OptimiserStepContext& _context, Block& _ast) +{ + ControlFlowSideEffectsCollector sideEffects(_context.dialect, _ast); + ConditionalUnsimplifier{_context.dialect, sideEffects.functionSideEffects()}(_ast); +} + void ConditionalUnsimplifier::operator()(Switch& _switch) { visit(*_switch.expression); @@ -78,7 +85,7 @@ void ConditionalUnsimplifier::operator()(Block& _block) YulString condition = std::get(*_if.condition).name; if ( holds_alternative(_stmt2) && - TerminationFinder(m_dialect).controlFlowKind(_if.body.statements.back()) != + TerminationFinder(m_dialect, &m_functionSideEffects).controlFlowKind(_if.body.statements.back()) != TerminationFinder::ControlFlow::FlowOut ) { diff --git a/libyul/optimiser/ConditionalUnsimplifier.h b/libyul/optimiser/ConditionalUnsimplifier.h index 975011b95..8025b661b 100644 --- a/libyul/optimiser/ConditionalUnsimplifier.h +++ b/libyul/optimiser/ConditionalUnsimplifier.h @@ -33,20 +33,21 @@ class ConditionalUnsimplifier: public ASTModifier { public: static constexpr char const* name{"ConditionalUnsimplifier"}; - static void run(OptimiserStepContext& _context, Block& _ast) - { - ConditionalUnsimplifier{_context.dialect}(_ast); - } + static void run(OptimiserStepContext& _context, Block& _ast); using ASTModifier::operator(); void operator()(Switch& _switch) override; void operator()(Block& _block) override; private: - explicit ConditionalUnsimplifier(Dialect const& _dialect): - m_dialect(_dialect) + explicit ConditionalUnsimplifier( + Dialect const& _dialect, + std::map const& _sideEffects + ): + m_dialect(_dialect), m_functionSideEffects(_sideEffects) {} Dialect const& m_dialect; + std::map const& m_functionSideEffects; }; } diff --git a/libyul/optimiser/DeadCodeEliminator.cpp b/libyul/optimiser/DeadCodeEliminator.cpp index 6a279487f..ad127a910 100644 --- a/libyul/optimiser/DeadCodeEliminator.cpp +++ b/libyul/optimiser/DeadCodeEliminator.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -36,7 +37,11 @@ using namespace solidity::yul; void DeadCodeEliminator::run(OptimiserStepContext& _context, Block& _ast) { - DeadCodeEliminator{_context.dialect}(_ast); + ControlFlowSideEffectsCollector sideEffects(_context.dialect, _ast); + DeadCodeEliminator{ + _context.dialect, + sideEffects.functionSideEffects() + }(_ast); } void DeadCodeEliminator::operator()(ForLoop& _for) @@ -49,7 +54,7 @@ void DeadCodeEliminator::operator()(Block& _block) { TerminationFinder::ControlFlow controlFlowChange; size_t index; - tie(controlFlowChange, index) = TerminationFinder{m_dialect}.firstUnconditionalControlFlowChange(_block.statements); + tie(controlFlowChange, index) = TerminationFinder{m_dialect, &m_functionSideEffects}.firstUnconditionalControlFlowChange(_block.statements); // Erase everything after the terminating statement that is not a function definition. if (controlFlowChange != TerminationFinder::ControlFlow::FlowOut && index != std::numeric_limits::max()) diff --git a/libyul/optimiser/DeadCodeEliminator.h b/libyul/optimiser/DeadCodeEliminator.h index d47bf86ea..98202fc94 100644 --- a/libyul/optimiser/DeadCodeEliminator.h +++ b/libyul/optimiser/DeadCodeEliminator.h @@ -31,12 +31,15 @@ namespace solidity::yul { struct Dialect; struct OptimiserStepContext; +struct ControlFlowSideEffects; /** * Optimisation stage that removes unreachable code * * Unreachable code is any code within a block which is preceded by a - * leave, return, invalid, break, continue, selfdestruct or revert. + * leave, return, invalid, break, continue, selfdestruct or revert or + * a call to a user-defined function that never returns (either due to + * recursion or a call to return / revert / stop). * * Function definitions are retained as they might be called by earlier * code and thus are considered reachable. @@ -57,9 +60,13 @@ public: void operator()(Block& _block) override; private: - DeadCodeEliminator(Dialect const& _dialect): m_dialect(_dialect) {} + DeadCodeEliminator( + Dialect const& _dialect, + std::map const& _sideEffects + ): m_dialect(_dialect), m_functionSideEffects(_sideEffects) {} Dialect const& m_dialect; + std::map const& m_functionSideEffects; }; } diff --git a/libyul/optimiser/Semantics.cpp b/libyul/optimiser/Semantics.cpp index bdd08710e..12349394a 100644 --- a/libyul/optimiser/Semantics.cpp +++ b/libyul/optimiser/Semantics.cpp @@ -182,8 +182,19 @@ pair TerminationFinder::firstUncondition TerminationFinder::ControlFlow TerminationFinder::controlFlowKind(Statement const& _statement) { if ( + holds_alternative(_statement) && + std::get(_statement).value && + containsNonContinuingFunctionCall(*std::get(_statement).value) + ) + return ControlFlow::Terminate; + else if ( + holds_alternative(_statement) && + containsNonContinuingFunctionCall(*std::get(_statement).value) + ) + return ControlFlow::Terminate; + else if ( holds_alternative(_statement) && - isTerminatingBuiltin(std::get(_statement)) + containsNonContinuingFunctionCall(std::get(_statement).expression) ) return ControlFlow::Terminate; else if (holds_alternative(_statement)) @@ -196,10 +207,18 @@ TerminationFinder::ControlFlow TerminationFinder::controlFlowKind(Statement cons return ControlFlow::FlowOut; } -bool TerminationFinder::isTerminatingBuiltin(ExpressionStatement const& _exprStmnt) +bool TerminationFinder::containsNonContinuingFunctionCall(Expression const& _expr) { - if (holds_alternative(_exprStmnt.expression)) - if (auto instruction = toEVMInstruction(m_dialect, std::get(_exprStmnt.expression).functionName.name)) - return evmasm::SemanticInformation::terminatesControlFlow(*instruction); + if (auto functionCall = std::get_if(&_expr)) + { + for (auto const& arg: functionCall->arguments) + if (containsNonContinuingFunctionCall(arg)) + return true; + + if (auto builtin = m_dialect.builtin(functionCall->functionName.name)) + return !builtin->controlFlowSideEffects.canContinue; + else if (m_functionSideEffects && m_functionSideEffects->count(functionCall->functionName.name)) + return !m_functionSideEffects->at(functionCall->functionName.name).canContinue; + } return false; } diff --git a/libyul/optimiser/Semantics.h b/libyul/optimiser/Semantics.h index 75ea40151..32b9c9b58 100644 --- a/libyul/optimiser/Semantics.h +++ b/libyul/optimiser/Semantics.h @@ -205,22 +205,31 @@ private: std::set m_variableReferences; }; +struct ControlFlowSideEffects; /** * Helper class to find "irregular" control flow. - * This includes termination, break and continue. + * This includes termination, break, continue and leave. + * In general, it is applied only to "simple" statements. The control-flow + * of loops, switches and if statements is always "FlowOut" with the assumption + * that the caller will descend into them. */ class TerminationFinder { public: - // TODO check all uses of TerminationFinder! + /// "Terminate" here means that there is no continuing control-flow. + /// If this is applied to a function that can revert or stop, but can also + /// exit regularly, the property is set to "FlowOut". enum class ControlFlow { FlowOut, Break, Continue, Terminate, Leave }; - TerminationFinder(Dialect const& _dialect): m_dialect(_dialect) {} + TerminationFinder( + Dialect const& _dialect, + std::map const* _functionSideEffects = nullptr + ): m_dialect(_dialect), m_functionSideEffects(_functionSideEffects) {} /// @returns the index of the first statement in the provided sequence /// that is an unconditional ``break``, ``continue``, ``leave`` or a - /// call to a terminating builtin function. + /// call to a terminating function. /// If control flow can continue at the end of the list, /// returns `FlowOut` and ``size_t(-1)``. /// The function might return ``FlowOut`` even though control @@ -233,13 +242,14 @@ public: /// This function could return FlowOut even if control flow never continues. ControlFlow controlFlowKind(Statement const& _statement); - /// @returns true if the expression statement is a direct - /// call to a builtin terminating function like - /// ``stop``, ``revert`` or ``return``. - bool isTerminatingBuiltin(ExpressionStatement const& _exprStmnt); + /// @returns true if the expression contains a + /// call to a terminating function, i.e. a function that does not have + /// a regular "flow out" control-flow (it might also be recursive). + bool containsNonContinuingFunctionCall(Expression const& _expr); private: Dialect const& m_dialect; + std::map const* m_functionSideEffects; }; } From 3996d0a34363d1b8b489b40aac204ec1adf11cb4 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 25 Oct 2021 16:54:29 +0200 Subject: [PATCH 13/69] Update tests. --- .../dead_code_user_functions.yul | 44 +++++++++++++++++++ .../function_after_revert.yul | 6 +-- .../fullSuite/name_cleaner_reserved.yul | 8 ++-- ...nusedFunctionParameterPruner_recursion.yul | 16 ++++--- 4 files changed, 61 insertions(+), 13 deletions(-) create mode 100644 test/libyul/yulOptimizerTests/deadCodeEliminator/dead_code_user_functions.yul diff --git a/test/libyul/yulOptimizerTests/deadCodeEliminator/dead_code_user_functions.yul b/test/libyul/yulOptimizerTests/deadCodeEliminator/dead_code_user_functions.yul new file mode 100644 index 000000000..00293d71d --- /dev/null +++ b/test/libyul/yulOptimizerTests/deadCodeEliminator/dead_code_user_functions.yul @@ -0,0 +1,44 @@ +{ + switch calldataload(0) + case 0 { + recursive() + sstore(0, 1) + } + case 1 { + terminating() + sstore(0, 7) + } + case 2 { + reverting() + sstore(0, 7) + } + + + function recursive() + { + recursive() + } + function terminating() + { + return(0, 0) + } + function reverting() + { + revert(0, 0) + } +} +// ---- +// step: deadCodeEliminator +// +// { +// switch calldataload(0) +// case 0 { recursive() } +// case 1 { terminating() } +// case 2 { reverting() } +// function recursive() +// { recursive() } +// function terminating() +// { return(0, 0) } +// function reverting() +// { revert(0, 0) } +// } diff --git a/test/libyul/yulOptimizerTests/deadCodeEliminator/function_after_revert.yul b/test/libyul/yulOptimizerTests/deadCodeEliminator/function_after_revert.yul index d5df28fb0..a75636b76 100644 --- a/test/libyul/yulOptimizerTests/deadCodeEliminator/function_after_revert.yul +++ b/test/libyul/yulOptimizerTests/deadCodeEliminator/function_after_revert.yul @@ -5,9 +5,7 @@ function fun() { - return(1, 1) - - pop(sub(10, 5)) + sstore(0, 1) } pop(add(1, 1)) @@ -19,5 +17,5 @@ // fun() // revert(0, 0) // function fun() -// { return(1, 1) } +// { sstore(0, 1) } // } diff --git a/test/libyul/yulOptimizerTests/fullSuite/name_cleaner_reserved.yul b/test/libyul/yulOptimizerTests/fullSuite/name_cleaner_reserved.yul index 576f5abb9..851ccbce2 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/name_cleaner_reserved.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/name_cleaner_reserved.yul @@ -1,11 +1,11 @@ { // This function name can be shortened, the other cannot. function nonmstore_(x) { - nonmstore_(x) + if calldataload(0) { nonmstore_(x) } sstore(10, calldataload(2)) } function mstore_(x) -> y { - let t3_3_ := mstore_(x) + if calldataload(0) { let t3_3_ := mstore_(x) } y := 8 sstore(y, calldataload(y)) } @@ -22,12 +22,12 @@ // } // function nonmstore(x) // { -// nonmstore(x) +// if calldataload(0) { nonmstore(x) } // sstore(10, calldataload(2)) // } // function mstore_(x) -> y // { -// pop(mstore_(x)) +// if calldataload(0) { pop(mstore_(x)) } // y := 8 // sstore(y, calldataload(y)) // } diff --git a/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_recursion.yul b/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_recursion.yul index 69b4517eb..c3b75e84e 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_recursion.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_recursion.yul @@ -5,7 +5,9 @@ sstore(1, l) function f(a, b, c) -> x, y, z { - x, y, z := f(1, 2, 3) + if calldataload(0) { + x, y, z := f(1, 2, 3) + } x := add(x, 1) } } @@ -21,9 +23,13 @@ // } // function f() -> x, y, z // { -// let x_1, y_1, z_1 := f() -// y := y_1 -// z := z_1 -// x := add(x_1, 1) +// if calldataload(0) +// { +// let x_1, y_1, z_1 := f() +// x := x_1 +// y := y_1 +// z := z_1 +// } +// x := add(x, 1) // } // } From 7f7c5ca171b33d1bcbbebfdbc5c887509d60fdf9 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 2 Nov 2021 11:50:37 +0100 Subject: [PATCH 14/69] New tests. --- .../side_effects_of_functions.yul | 38 +++++++++++++++++++ .../side_effects_of_functions.yul | 38 +++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 test/libyul/yulOptimizerTests/conditionalSimplifier/side_effects_of_functions.yul create mode 100644 test/libyul/yulOptimizerTests/conditionalUnsimplifier/side_effects_of_functions.yul diff --git a/test/libyul/yulOptimizerTests/conditionalSimplifier/side_effects_of_functions.yul b/test/libyul/yulOptimizerTests/conditionalSimplifier/side_effects_of_functions.yul new file mode 100644 index 000000000..c448fdf02 --- /dev/null +++ b/test/libyul/yulOptimizerTests/conditionalSimplifier/side_effects_of_functions.yul @@ -0,0 +1,38 @@ +{ + function recursive() { recursive() } + function terminating() { stop() } + function maybeReverting() { if calldataload(0) { revert(0, 0) } } + + let a := calldataload(7) + if a { recursive() } + + a := calldataload(a) + if a { maybeReverting() } + + a := calldataload(a) + if a { terminating() } + + sstore(0, a) +} +// ---- +// step: conditionalSimplifier +// +// { +// function recursive() +// { recursive() } +// function terminating() +// { stop() } +// function maybeReverting() +// { +// if calldataload(0) { revert(0, 0) } +// } +// let a := calldataload(7) +// if a { recursive() } +// a := 0 +// a := calldataload(a) +// if a { maybeReverting() } +// a := calldataload(a) +// if a { terminating() } +// a := 0 +// sstore(0, a) +// } diff --git a/test/libyul/yulOptimizerTests/conditionalUnsimplifier/side_effects_of_functions.yul b/test/libyul/yulOptimizerTests/conditionalUnsimplifier/side_effects_of_functions.yul new file mode 100644 index 000000000..25e17d75a --- /dev/null +++ b/test/libyul/yulOptimizerTests/conditionalUnsimplifier/side_effects_of_functions.yul @@ -0,0 +1,38 @@ +{ + function recursive() { recursive() } + function terminating() { stop() } + function maybeReverting() { if calldataload(0) { revert(0, 0) } } + + let a := calldataload(7) + if a { recursive() } + a := 0 + + a := calldataload(a) + if a { maybeReverting() } + + a := calldataload(a) + if a { terminating() } + a := 0 + + sstore(0, a) +} +// ---- +// step: conditionalUnsimplifier +// +// { +// function recursive() +// { recursive() } +// function terminating() +// { stop() } +// function maybeReverting() +// { +// if calldataload(0) { revert(0, 0) } +// } +// let a := calldataload(7) +// if a { recursive() } +// a := calldataload(a) +// if a { maybeReverting() } +// a := calldataload(a) +// if a { terminating() } +// sstore(0, a) +// } From be6fb5f3d658f914a60dc99016165ced956a6519 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 2 Nov 2021 11:54:10 +0100 Subject: [PATCH 15/69] Changelog entry. --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index 4cfbe6637..c724693ee 100644 --- a/Changelog.md +++ b/Changelog.md @@ -12,6 +12,7 @@ Compiler Features: * 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``. * Standard JSON: Accept nested brackets in step sequences passed to ``settings.optimizer.details.yulDetails.optimizerSteps``. * 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. + * Yul Optimizer: Take control-flow side-effects of user-defined functions into account in various optimizer steps. Bugfixes: From 93c1fe68789ae23c610570c70685d0c6a9aa8a12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 11 Oct 2021 13:03:51 +0200 Subject: [PATCH 16/69] Treat --help, --license and --version as separate input modes --- solc/CommandLineInterface.cpp | 66 ++++++++++++++++++++++++---- solc/CommandLineInterface.h | 2 + solc/CommandLineParser.cpp | 69 +++++++++++------------------- solc/CommandLineParser.h | 28 ++++-------- test/solc/CommandLineInterface.cpp | 39 ++++++++++++++++- test/solc/CommandLineParser.cpp | 62 +++++++++++++-------------- 6 files changed, 160 insertions(+), 106 deletions(-) diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 6c24b7742..e86381bf3 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -23,6 +23,7 @@ */ #include +#include "license.h" #include "solidity/BuildInfo.h" #include @@ -405,6 +406,13 @@ bool CommandLineInterface::readInputFiles() { solAssert(!m_standardJsonInput.has_value(), ""); + if ( + m_options.input.mode == InputMode::Help || + m_options.input.mode == InputMode::License || + m_options.input.mode == InputMode::Version + ) + return true; + m_fileReader.setBasePath(m_options.input.basePath); if (m_fileReader.basePath() != "") @@ -573,8 +581,18 @@ void CommandLineInterface::createJson(string const& _fileName, string const& _js bool CommandLineInterface::parseArguments(int _argc, char const* const* _argv) { - CommandLineParser parser(sout(/* _markAsUsed */ false), serr(/* _markAsUsed */ false)); - bool success = parser.parse(_argc, _argv, isatty(fileno(stdin))); + CommandLineParser parser(serr(/* _markAsUsed */ false)); + + if (isatty(fileno(stdin)) && _argc == 1) + { + // If the terminal is taking input from the user, provide more user-friendly output. + CommandLineParser::printHelp(sout()); + + // In this case we want to exit with an error but not display any error message. + return false; + } + + bool success = parser.parse(_argc, _argv); if (!success) return false; m_hasOutput = m_hasOutput || parser.hasOutput(); @@ -587,6 +605,15 @@ bool CommandLineInterface::processInput() { switch (m_options.input.mode) { + case InputMode::Help: + CommandLineParser::printHelp(sout()); + return false; + case InputMode::License: + printLicense(); + return true; + case InputMode::Version: + printVersion(); + return true; case InputMode::StandardJson: { solAssert(m_standardJsonInput.has_value(), ""); @@ -611,6 +638,19 @@ bool CommandLineInterface::processInput() return false; } +void CommandLineInterface::printVersion() +{ + sout() << "solc, the solidity compiler commandline interface" << endl; + sout() << "Version: " << solidity::frontend::VersionString << endl; +} + +void CommandLineInterface::printLicense() +{ + sout() << otherLicenses << endl; + // This is a static variable generated by cmake from LICENSE.txt + sout() << licenseText << endl; +} + bool CommandLineInterface::compile() { solAssert(m_options.input.mode == InputMode::Compiler || m_options.input.mode == InputMode::CompilerWithASTImport, ""); @@ -845,16 +885,24 @@ void CommandLineInterface::handleAst() bool CommandLineInterface::actOnInput() { - if (m_options.input.mode == InputMode::StandardJson || m_options.input.mode == InputMode::Assembler) - // Already done in "processInput" phase. - return true; - else if (m_options.input.mode == InputMode::Linker) - writeLinkedFiles(); - else + switch (m_options.input.mode) { - solAssert(m_options.input.mode == InputMode::Compiler || m_options.input.mode == InputMode::CompilerWithASTImport, ""); + case InputMode::Help: + case InputMode::License: + case InputMode::Version: + case InputMode::StandardJson: + case InputMode::Assembler: + // Already done in "processInput" phase. + break; + case InputMode::Linker: + writeLinkedFiles(); + break; + case InputMode::Compiler: + case InputMode::CompilerWithASTImport: outputCompilationResults(); + break; } + return !m_outputFailed; } diff --git a/solc/CommandLineInterface.h b/solc/CommandLineInterface.h index 1ca40568c..e99ed1c07 100644 --- a/solc/CommandLineInterface.h +++ b/solc/CommandLineInterface.h @@ -66,6 +66,8 @@ public: std::optional const& standardJsonInput() const { return m_standardJsonInput; } private: + void printVersion(); + void printLicense(); bool compile(); bool link(); void writeLinkedFiles(); diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index 22d92d463..c3448ff8f 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -16,8 +16,6 @@ */ // SPDX-License-Identifier: GPL-3.0 -#include "license.h" - #include #include #include @@ -36,19 +34,12 @@ namespace po = boost::program_options; namespace solidity::frontend { -ostream& CommandLineParser::sout() -{ - m_hasOutput = true; - return m_sout; -} - ostream& CommandLineParser::serr() { m_hasOutput = true; return m_serr; } -#define cout #define cerr static string const g_strAllowPaths = "allow-paths"; @@ -147,26 +138,6 @@ static map const g_inputModeName = { {InputMode::Linker, "linker"}, }; -void CommandLineParser::printVersionAndExit() -{ - sout() << - "solc, the solidity compiler commandline interface" << - endl << - "Version: " << - solidity::frontend::VersionString << - endl; - exit(EXIT_SUCCESS); -} - -void CommandLineParser::printLicenseAndExit() -{ - sout() << otherLicenses << endl; - // This is a static variable generated by cmake from LICENSE.txt - sout() << licenseText << endl; - exit(EXIT_SUCCESS); -} - - bool CommandLineParser::checkMutuallyExclusive(vector const& _optionNames) { if (countEnabledOptions(_optionNames) > 1) @@ -297,11 +268,11 @@ OptimiserSettings CommandLineOptions::optimiserSettings() const return settings; } -bool CommandLineParser::parse(int _argc, char const* const* _argv, bool _interactiveTerminal) +bool CommandLineParser::parse(int _argc, char const* const* _argv) { m_hasOutput = false; - if (!parseArgs(_argc, _argv, _interactiveTerminal)) + if (!parseArgs(_argc, _argv)) return false; return processArgs(); @@ -482,6 +453,10 @@ bool CommandLineParser::parseOutputSelection() switch (_mode) { + case InputMode::Help: + case InputMode::License: + case InputMode::Version: + solAssert(false); case InputMode::Compiler: case InputMode::CompilerWithASTImport: return contains(compilerModeOutputs, _outputName); @@ -847,7 +822,7 @@ po::positional_options_description CommandLineParser::positionalOptionsDescripti return filesPositions; } -bool CommandLineParser::parseArgs(int _argc, char const* const* _argv, bool _interactiveTerminal) +bool CommandLineParser::parseArgs(int _argc, char const* const* _argv) { po::options_description allOptions = optionsDescription(); po::positional_options_description filesPositions = positionalOptionsDescription(); @@ -866,18 +841,6 @@ bool CommandLineParser::parseArgs(int _argc, char const* const* _argv, bool _int return false; } - if (m_args.count(g_strHelp) || (_interactiveTerminal && _argc == 1)) - { - sout() << allOptions; - return false; - } - - if (m_args.count(g_strVersion)) - printVersionAndExit(); - - if (m_args.count(g_strLicense)) - printLicenseAndExit(); - po::notify(m_args); return true; @@ -886,6 +849,9 @@ bool CommandLineParser::parseArgs(int _argc, char const* const* _argv, bool _int bool CommandLineParser::processArgs() { if (!checkMutuallyExclusive({ + g_strHelp, + g_strLicense, + g_strVersion, g_strStandardJSON, g_strLink, g_strAssemble, @@ -895,7 +861,13 @@ bool CommandLineParser::processArgs() })) return false; - if (m_args.count(g_strStandardJSON) > 0) + if (m_args.count(g_strHelp) > 0) + m_options.input.mode = InputMode::Help; + else if (m_args.count(g_strLicense) > 0) + m_options.input.mode = InputMode::License; + else if (m_args.count(g_strVersion) > 0) + m_options.input.mode = InputMode::Version; + else if (m_args.count(g_strStandardJSON) > 0) m_options.input.mode = InputMode::StandardJson; else if (m_args.count(g_strAssemble) > 0 || m_args.count(g_strStrictAssembly) > 0 || m_args.count(g_strYul) > 0) m_options.input.mode = InputMode::Assembler; @@ -906,6 +878,13 @@ bool CommandLineParser::processArgs() else m_options.input.mode = InputMode::Compiler; + if ( + m_options.input.mode == InputMode::Help || + m_options.input.mode == InputMode::License || + m_options.input.mode == InputMode::Version + ) + return true; + map> validOptionInputModeCombinations = { // TODO: This should eventually contain all options. {g_strErrorRecovery, {InputMode::Compiler, InputMode::CompilerWithASTImport}}, diff --git a/solc/CommandLineParser.h b/solc/CommandLineParser.h index ad525ea3b..27a64c7b9 100644 --- a/solc/CommandLineParser.h +++ b/solc/CommandLineParser.h @@ -48,6 +48,9 @@ namespace solidity::frontend enum class InputMode { + Help, + License, + Version, Compiler, CompilerWithASTImport, StandardJson, @@ -230,34 +233,28 @@ struct CommandLineOptions /// Parses the command-line arguments and produces a filled-out CommandLineOptions structure. /// Validates provided values and prints error messages in case of errors. -/// -/// The class is also responsible for handling options that only result in printing informational -/// text, without the need to invoke the compiler - printing usage banner, version or license. class CommandLineParser { public: - explicit CommandLineParser(std::ostream& _sout, std::ostream& _serr): - m_sout(_sout), + explicit CommandLineParser(std::ostream& _serr): m_serr(_serr) {} /// Parses the command-line arguments and fills out the internal CommandLineOptions structure. - /// Performs validation and prints error messages. If requested, prints usage banner, version - /// or license. - /// @param interactiveTerminal specifies whether the terminal is taking input from the user. - /// This is used to determine whether to provide more user-friendly output in some situations. - /// E.g. whether to print help text when no arguments are provided. + /// Performs validation and prints error messages. /// @return true if there were no validation errors when parsing options and the /// CommandLineOptions structure has been fully initialized. false if there were errors - in /// this case CommandLineOptions may be only partially filled out. May also return false if /// there is not further processing necessary and the program should just exit. - bool parse(int _argc, char const* const* _argv, bool _interactiveTerminal); + bool parse(int _argc, char const* const* _argv); CommandLineOptions const& options() const { return m_options; } /// Returns true if the parser has written anything to any of its output streams. bool hasOutput() const { return m_hasOutput; } + static void printHelp(std::ostream& _out) { _out << optionsDescription(); } + private: /// @returns a specification of all named command-line options accepted by the compiler. /// The object can be used to parse command-line arguments or to generate the help screen. @@ -270,7 +267,7 @@ private: /// Uses boost::program_options to parse the command-line arguments and leaves the result in @a m_args. /// Also handles the arguments that result in information being printed followed by immediate exit. /// @returns false if parsing fails due to syntactical errors or the arguments not matching the description. - bool parseArgs(int _argc, char const* const* _argv, bool _interactiveTerminal); + bool parseArgs(int _argc, char const* const* _argv); /// Validates parsed arguments stored in @a m_args and fills out the internal CommandLineOptions /// structure. @@ -294,20 +291,13 @@ private: bool parseOutputSelection(); bool checkMutuallyExclusive(std::vector const& _optionNames); - [[noreturn]] void printVersionAndExit(); - [[noreturn]] void printLicenseAndExit(); size_t countEnabledOptions(std::vector const& _optionNames) const; static std::string joinOptionNames(std::vector const& _optionNames, std::string _separator = ", "); - /// Returns the stream that should receive normal output. Sets m_hasOutput to true if the - /// stream has ever been used. - std::ostream& sout(); - /// Returns the stream that should receive error output. Sets m_hasOutput to true if the /// stream has ever been used. std::ostream& serr(); - std::ostream& m_sout; std::ostream& m_serr; bool m_hasOutput = false; diff --git a/test/solc/CommandLineInterface.cpp b/test/solc/CommandLineInterface.cpp index 3d1fce7d2..739213e8f 100644 --- a/test/solc/CommandLineInterface.cpp +++ b/test/solc/CommandLineInterface.cpp @@ -29,6 +29,8 @@ #include +#include + #include #include @@ -110,9 +112,42 @@ namespace solidity::frontend::test BOOST_AUTO_TEST_SUITE(CommandLineInterfaceTest) +BOOST_AUTO_TEST_CASE(help) +{ + OptionsReaderAndMessages result = parseCommandLineAndReadInputFiles({"solc", "--help"}, "", /* _processInput */ true); + + BOOST_TEST(!result.success); + BOOST_TEST(boost::starts_with(result.stdoutContent, "solc, the Solidity commandline compiler.")); + BOOST_TEST(result.stderrContent == ""); + BOOST_TEST(result.options.input.mode == InputMode::Help); +} + +BOOST_AUTO_TEST_CASE(license) +{ + OptionsReaderAndMessages result = parseCommandLineAndReadInputFiles({"solc", "--license"}, "", /* _processInput */ true); + + BOOST_TEST(result.success); + BOOST_TEST(boost::starts_with(result.stdoutContent, "Most of the code is licensed under GPLv3")); + BOOST_TEST(result.stderrContent == ""); + BOOST_TEST(result.options.input.mode == InputMode::License); +} + +BOOST_AUTO_TEST_CASE(version) +{ + OptionsReaderAndMessages result = parseCommandLineAndReadInputFiles({"solc", "--version"}, "", /* _processInput */ true); + + BOOST_TEST(result.success); + BOOST_TEST(boost::ends_with(result.stdoutContent, "Version: " + solidity::frontend::VersionString + "\n")); + BOOST_TEST(result.stderrContent == ""); + BOOST_TEST(result.options.input.mode == InputMode::Version); +} + BOOST_AUTO_TEST_CASE(multiple_input_modes) { - array inputModeOptions = { + array inputModeOptions = { + "--help", + "--license", + "--version", "--standard-json", "--link", "--assemble", @@ -122,7 +157,7 @@ BOOST_AUTO_TEST_CASE(multiple_input_modes) }; string expectedMessage = "The following options are mutually exclusive: " - "--standard-json, --link, --assemble, --strict-assembly, --yul, --import-ast. " + "--help, --license, --version, --standard-json, --link, --assemble, --strict-assembly, --yul, --import-ast. " "Select at most one.\n"; for (string const& mode1: inputModeOptions) diff --git a/test/solc/CommandLineParser.cpp b/test/solc/CommandLineParser.cpp index 663bf022c..a9ba08d81 100644 --- a/test/solc/CommandLineParser.cpp +++ b/test/solc/CommandLineParser.cpp @@ -30,8 +30,6 @@ #include #include -#include - #include #include #include @@ -48,16 +46,12 @@ using namespace solidity::yul; namespace { -optional parseCommandLine(vector const& _commandLine, ostream& _stdout, ostream& _stderr) +optional parseCommandLine(vector const& _commandLine, ostream& _stderr) { vector argv = test::makeArgv(_commandLine); - CommandLineParser cliParser(_stdout, _stderr); - bool success = cliParser.parse( - static_cast(_commandLine.size()), - argv.data(), - false // interactiveTerminal - ); + CommandLineParser cliParser(_stderr); + bool success = cliParser.parse(static_cast(_commandLine.size()), argv.data()); if (!success) return nullopt; @@ -81,24 +75,34 @@ BOOST_AUTO_TEST_CASE(no_options) expectedOptions.modelChecker.initialize = true; expectedOptions.modelChecker.settings = {}; - stringstream sout, serr; - optional parsedOptions = parseCommandLine(commandLine, sout, serr); + stringstream serr; + optional parsedOptions = parseCommandLine(commandLine, serr); - BOOST_TEST(sout.str() == ""); BOOST_TEST(serr.str() == ""); BOOST_REQUIRE(parsedOptions.has_value()); BOOST_TEST(parsedOptions.value() == expectedOptions); } -BOOST_AUTO_TEST_CASE(help) +BOOST_AUTO_TEST_CASE(help_license_version) { - stringstream sout, serr; - optional parsedOptions = parseCommandLine({"solc", "--help"}, sout, serr); + map expectedModePerOption = { + {"--help", InputMode::Help}, + {"--license", InputMode::License}, + {"--version", InputMode::Version}, + }; - BOOST_TEST(serr.str() == ""); - BOOST_TEST(boost::starts_with(sout.str(), "solc, the Solidity commandline compiler.")); - BOOST_TEST(sout.str().find("Usage: solc [options] [input_file...]") != string::npos); - BOOST_TEST(!parsedOptions.has_value()); + for (auto const& [option, expectedMode]: expectedModePerOption) + { + stringstream serr; + optional parsedOptions = parseCommandLine({"solc", option}, serr); + + CommandLineOptions expectedOptions; + expectedOptions.input.mode = expectedMode; + + BOOST_TEST(serr.str() == ""); + BOOST_REQUIRE(parsedOptions.has_value()); + BOOST_TEST(parsedOptions.value() == expectedOptions); + } } BOOST_AUTO_TEST_CASE(cli_mode_options) @@ -220,10 +224,9 @@ BOOST_AUTO_TEST_CASE(cli_mode_options) 5, }; - stringstream sout, serr; - optional parsedOptions = parseCommandLine(commandLine, sout, serr); + stringstream serr; + optional parsedOptions = parseCommandLine(commandLine, serr); - BOOST_TEST(sout.str() == ""); BOOST_TEST(serr.str() == ""); BOOST_REQUIRE(parsedOptions.has_value()); BOOST_TEST(parsedOptions.value() == expectedOptions); @@ -337,10 +340,9 @@ BOOST_AUTO_TEST_CASE(assembly_mode_options) expectedOptions.optimizer.expectedExecutionsPerDeployment = 1000; } - stringstream sout, serr; - optional parsedOptions = parseCommandLine(commandLine, sout, serr); + stringstream serr; + optional parsedOptions = parseCommandLine(commandLine, serr); - BOOST_TEST(sout.str() == ""); BOOST_TEST(serr.str() == "Warning: Yul is still experimental. Please use the output with care.\n"); BOOST_REQUIRE(parsedOptions.has_value()); BOOST_TEST(parsedOptions.value() == expectedOptions); @@ -406,10 +408,9 @@ BOOST_AUTO_TEST_CASE(standard_json_mode_options) expectedOptions.compiler.combinedJsonRequests->abi = true; expectedOptions.compiler.combinedJsonRequests->binary = true; - stringstream sout, serr; - optional parsedOptions = parseCommandLine(commandLine, sout, serr); + stringstream serr; + optional parsedOptions = parseCommandLine(commandLine, serr); - BOOST_TEST(sout.str() == ""); BOOST_TEST(serr.str() == ""); BOOST_REQUIRE(parsedOptions.has_value()); BOOST_TEST(parsedOptions.value() == expectedOptions); @@ -426,11 +427,10 @@ BOOST_AUTO_TEST_CASE(invalid_options_input_modes_combinations) for (auto const& [optionName, inputModes]: invalidOptionInputModeCombinations) for (string const& inputMode: inputModes) { - stringstream sout, serr; + stringstream serr; vector commandLine = {"solc", optionName, "file", inputMode}; - optional parsedOptions = parseCommandLine(commandLine, sout, serr); + optional parsedOptions = parseCommandLine(commandLine, serr); - BOOST_TEST(sout.str() == ""); BOOST_TEST(serr.str() == "The following options are not supported in the current input mode: " + optionName + "\n"); BOOST_REQUIRE(!parsedOptions.has_value()); } From a1c9c1e2b5bbe87e70a7179353b305c80fba34eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 11 Oct 2021 13:17:01 +0200 Subject: [PATCH 17/69] CommandLineInterface: Merge processInput() and actOnInput() - The distinction between them is not as clear-cut as it should be. For example processInput() prints output in assembly mode. --- solc/CommandLineInterface.cpp | 47 +++++++++++------------------------ solc/CommandLineInterface.h | 5 +--- solc/main.cpp | 3 +-- test/solc/Common.cpp | 6 ++++- 4 files changed, 21 insertions(+), 40 deletions(-) diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index e86381bf3..1358dd484 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -610,10 +610,10 @@ bool CommandLineInterface::processInput() return false; case InputMode::License: printLicense(); - return true; + break; case InputMode::Version: printVersion(); - return true; + break; case InputMode::StandardJson: { solAssert(m_standardJsonInput.has_value(), ""); @@ -621,21 +621,25 @@ bool CommandLineInterface::processInput() StandardCompiler compiler(m_fileReader.reader(), m_options.formatting.json); sout() << compiler.compile(move(m_standardJsonInput.value())) << endl; m_standardJsonInput.reset(); - return true; + break; } case InputMode::Assembler: - { - return assemble(m_options.assembly.inputLanguage, m_options.assembly.targetMachine); - } + if (!assemble(m_options.assembly.inputLanguage, m_options.assembly.targetMachine)) + return false; + break; case InputMode::Linker: - return link(); + if (!link()) + return false; + writeLinkedFiles(); + break; case InputMode::Compiler: case InputMode::CompilerWithASTImport: - return compile(); + if (!compile()) + return false; + outputCompilationResults(); } - solAssert(false, ""); - return false; + return !m_outputFailed; } void CommandLineInterface::printVersion() @@ -883,29 +887,6 @@ void CommandLineInterface::handleAst() } } -bool CommandLineInterface::actOnInput() -{ - switch (m_options.input.mode) - { - case InputMode::Help: - case InputMode::License: - case InputMode::Version: - case InputMode::StandardJson: - case InputMode::Assembler: - // Already done in "processInput" phase. - break; - case InputMode::Linker: - writeLinkedFiles(); - break; - case InputMode::Compiler: - case InputMode::CompilerWithASTImport: - outputCompilationResults(); - break; - } - - return !m_outputFailed; -} - bool CommandLineInterface::link() { solAssert(m_options.input.mode == InputMode::Linker, ""); diff --git a/solc/CommandLineInterface.h b/solc/CommandLineInterface.h index e99ed1c07..ee5057468 100644 --- a/solc/CommandLineInterface.h +++ b/solc/CommandLineInterface.h @@ -55,11 +55,8 @@ public: bool parseArguments(int _argc, char const* const* _argv); /// Read the content of all input files and initialize the file reader. bool readInputFiles(); - /// Parse the files and create source code objects + /// Parse the files, create source code objects, print the output. bool processInput(); - /// Perform actions on the input depending on provided compiler arguments - /// @returns true on success. - bool actOnInput(); CommandLineOptions const& options() const { return m_options; } FileReader const& fileReader() const { return m_fileReader; } diff --git a/solc/main.cpp b/solc/main.cpp index 1299e2564..874ee13ca 100644 --- a/solc/main.cpp +++ b/solc/main.cpp @@ -65,8 +65,7 @@ int main(int argc, char** argv) bool success = cli.parseArguments(argc, argv) && cli.readInputFiles() && - cli.processInput() && - cli.actOnInput(); + cli.processInput(); return success ? 0 : 1; } diff --git a/test/solc/Common.cpp b/test/solc/Common.cpp index 28263e21e..8e40c1af6 100644 --- a/test/solc/Common.cpp +++ b/test/solc/Common.cpp @@ -70,6 +70,10 @@ string test::stripPreReleaseWarning(string const& _stderrContent) R"(Warning( \(3805\))?: This is a pre-release compiler version, please do not use it in production\.\n)" R"((\n)?)" }; + static regex const noOutputRegex{ + R"(Compiler run successful, no output requested\.\n)" + }; - return regex_replace(_stderrContent, preReleaseWarningRegex, ""); + string output = regex_replace(_stderrContent, preReleaseWarningRegex, ""); + return regex_replace(move(output), noOutputRegex, ""); } From 0417db0f6a8474468a74515edddcf6d27c5ba977 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 11 Oct 2021 13:30:08 +0200 Subject: [PATCH 18/69] Don't return an error from --help --- solc/CommandLineInterface.cpp | 2 +- test/solc/CommandLineInterface.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 1358dd484..9d2279910 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -607,7 +607,7 @@ bool CommandLineInterface::processInput() { case InputMode::Help: CommandLineParser::printHelp(sout()); - return false; + break; case InputMode::License: printLicense(); break; diff --git a/test/solc/CommandLineInterface.cpp b/test/solc/CommandLineInterface.cpp index 739213e8f..0269ec462 100644 --- a/test/solc/CommandLineInterface.cpp +++ b/test/solc/CommandLineInterface.cpp @@ -116,7 +116,7 @@ BOOST_AUTO_TEST_CASE(help) { OptionsReaderAndMessages result = parseCommandLineAndReadInputFiles({"solc", "--help"}, "", /* _processInput */ true); - BOOST_TEST(!result.success); + BOOST_TEST(result.success); BOOST_TEST(boost::starts_with(result.stdoutContent, "solc, the Solidity commandline compiler.")); BOOST_TEST(result.stderrContent == ""); BOOST_TEST(result.options.input.mode == InputMode::Help); From 285528f407990112c5f52a3dc3c15d819b551eb4 Mon Sep 17 00:00:00 2001 From: Derek Brans Date: Tue, 2 Nov 2021 20:27:32 -0500 Subject: [PATCH 19/69] Added the BigSur 11.6 in the supported os list --- scripts/install_deps.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/install_deps.sh b/scripts/install_deps.sh index 6a9c12f3f..7540c8bdf 100755 --- a/scripts/install_deps.sh +++ b/scripts/install_deps.sh @@ -93,8 +93,8 @@ case $(uname -s) in 10.15) echo "Installing solidity dependencies on macOS 10.15 Catalina." ;; - 11.0 | 11.1 | 11.2 | 11.3 | 11.4 | 11.5) - echo "Installing solidity dependencies on macOS 11.0 / 11.1 / 11.2 / 11.3 / 11.4 / 11.5 Big Sur." + 11.0 | 11.1 | 11.2 | 11.3 | 11.4 | 11.5 | 11.6) + echo "Installing solidity dependencies on macOS 11.0 / 11.1 / 11.2 / 11.3 / 11.4 / 11.5 / 11.6 Big Sur." ;; *) echo "Unsupported macOS version." From e40cf92b1d34120506c648a7abc1db7734d65f4c Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Wed, 20 Oct 2021 16:21:34 +0200 Subject: [PATCH 20/69] [SMTChecker] Merge all entry points for a target --- libsolidity/formal/CHC.cpp | 27 ++++++++++--------- libsolidity/formal/CHC.h | 4 ++- .../model_checker_invariants_all/err | 1 - .../err | 1 - .../output.json | 2 -- .../external_reentrancy_crypto.sol | 2 +- .../base_contract_assertion_fail_1.sol | 2 +- .../implicit_constructor_hierarchy.sol | 3 +-- .../operators/conditional_assignment_5.sol | 4 ++- .../operators/conditional_assignment_6.sol | 2 +- 10 files changed, 24 insertions(+), 24 deletions(-) diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index bfdb0b428..c0a92264e 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -1623,28 +1623,23 @@ void CHC::checkVerificationTargets() // Also, all possible contexts in which an external function can be called has been recorded (m_queryPlaceholders). // Here we combine every context in which an external function can be called with all possible verification conditions // in its call graph. Each such combination forms a unique verification target. - vector verificationTargets; + map> targetEntryPoints; for (auto const& [function, placeholders]: m_queryPlaceholders) { auto functionTargets = transactionVerificationTargetsIds(function); for (auto const& placeholder: placeholders) for (unsigned id: functionTargets) - { - auto const& target = m_verificationTargets.at(id); - verificationTargets.push_back(CHCVerificationTarget{ - {target.type, placeholder.fromPredicate, placeholder.constraints && placeholder.errorExpression == target.errorId}, - target.errorId, - target.errorNode - }); - } + targetEntryPoints[id].push_back(placeholder); } set checkedErrorIds; - for (auto const& target: verificationTargets) + for (auto const& [targetId, placeholders]: targetEntryPoints) { string errorType; ErrorId errorReporterId; + auto const& target = m_verificationTargets.at(targetId); + if (target.type == VerificationTargetType::PopEmptyArray) { solAssert(dynamic_cast(target.errorNode), ""); @@ -1692,7 +1687,7 @@ void CHC::checkVerificationTargets() else solAssert(false, ""); - checkAndReportTarget(target, errorReporterId, errorType + " happens here.", errorType + " might happen here."); + checkAndReportTarget(target, placeholders, errorReporterId, errorType + " happens here.", errorType + " might happen here."); checkedErrorIds.insert(target.errorId); } @@ -1750,7 +1745,7 @@ void CHC::checkVerificationTargets() { set seenErrors; msg += " = 0 -> no errors\n"; - for (auto const& target: verificationTargets) + for (auto const& [id, target]: m_verificationTargets) if (!seenErrors.count(target.errorId)) { seenErrors.insert(target.errorId); @@ -1785,6 +1780,7 @@ void CHC::checkVerificationTargets() void CHC::checkAndReportTarget( CHCVerificationTarget const& _target, + vector const& _placeholders, ErrorId _errorReporterId, string _satMsg, string _unknownMsg @@ -1794,7 +1790,12 @@ void CHC::checkAndReportTarget( return; createErrorBlock(); - connectBlocks(_target.value, error(), _target.constraints); + for (auto const& placeholder: _placeholders) + connectBlocks( + placeholder.fromPredicate, + error(), + placeholder.constraints && placeholder.errorExpression == _target.errorId + ); auto const& location = _target.errorNode->location(); auto [result, invariant, model] = query(error(), location); if (result == CheckResult::UNSATISFIABLE) diff --git a/libsolidity/formal/CHC.h b/libsolidity/formal/CHC.h index d9e27a89c..1c74aa650 100644 --- a/libsolidity/formal/CHC.h +++ b/libsolidity/formal/CHC.h @@ -252,11 +252,13 @@ private: void verificationTargetEncountered(ASTNode const* const _errorNode, VerificationTargetType _type, smtutil::Expression const& _errorCondition); void checkVerificationTargets(); - // Forward declaration. Definition is below. + // Forward declarations. Definitions are below. struct CHCVerificationTarget; + struct CHCQueryPlaceholder; void checkAssertTarget(ASTNode const* _scope, CHCVerificationTarget const& _target); void checkAndReportTarget( CHCVerificationTarget const& _target, + std::vector const& _placeholders, langutil::ErrorId _errorReporterId, std::string _satMsg, std::string _unknownMsg = "" diff --git a/test/cmdlineTests/model_checker_invariants_all/err b/test/cmdlineTests/model_checker_invariants_all/err index 47bc04256..2f028037b 100644 --- a/test/cmdlineTests/model_checker_invariants_all/err +++ b/test/cmdlineTests/model_checker_invariants_all/err @@ -7,7 +7,6 @@ Warning: Return value of low-level calls not used. Info: Contract invariant(s) for model_checker_invariants_all/input.sol:test: (x <= 0) Reentrancy property(ies) for model_checker_invariants_all/input.sol:test: -(!(x <= 0) || (x' <= 0)) ((!(x <= 0) || !( >= 3)) && (!(x <= 0) || (x' <= 0))) ((!(x <= 0) || (x' <= 0)) && (!(x <= 0) || ( <= 0))) = 0 -> no errors diff --git a/test/cmdlineTests/model_checker_invariants_contract_reentrancy/err b/test/cmdlineTests/model_checker_invariants_contract_reentrancy/err index 372143657..fad76665e 100644 --- a/test/cmdlineTests/model_checker_invariants_contract_reentrancy/err +++ b/test/cmdlineTests/model_checker_invariants_contract_reentrancy/err @@ -7,7 +7,6 @@ Warning: Return value of low-level calls not used. Info: Contract invariant(s) for model_checker_invariants_contract_reentrancy/input.sol:test: (x <= 0) Reentrancy property(ies) for model_checker_invariants_contract_reentrancy/input.sol:test: -(!(x <= 0) || (x' <= 0)) ((!(x <= 0) || !( >= 3)) && (!(x <= 0) || (x' <= 0))) ((!(x <= 0) || (x' <= 0)) && (!(x <= 0) || ( <= 0))) = 0 -> no errors diff --git a/test/cmdlineTests/standard_model_checker_invariants_contract_reentrancy/output.json b/test/cmdlineTests/standard_model_checker_invariants_contract_reentrancy/output.json index 433648d0b..f5ced7253 100644 --- a/test/cmdlineTests/standard_model_checker_invariants_contract_reentrancy/output.json +++ b/test/cmdlineTests/standard_model_checker_invariants_contract_reentrancy/output.json @@ -7,7 +7,6 @@ ","message":"Return value of low-level calls not used.","severity":"warning","sourceLocation":{"end":143,"file":"A","start":132},"type":"Warning"},{"component":"general","errorCode":"1180","formattedMessage":"Info: Contract invariant(s) for A:test: (x <= 0) Reentrancy property(ies) for A:test: -(!(x <= 0) || (x' <= 0)) ((!(x <= 0) || !( >= 3)) && (!(x <= 0) || (x' <= 0))) ((!(x <= 0) || (x' <= 0)) && (!(x <= 0) || ( <= 0))) = 0 -> no errors @@ -18,7 +17,6 @@ Reentrancy property(ies) for A:test: ","message":"Contract invariant(s) for A:test: (x <= 0) Reentrancy property(ies) for A:test: -(!(x <= 0) || (x' <= 0)) ((!(x <= 0) || !( >= 3)) && (!(x <= 0) || (x' <= 0))) ((!(x <= 0) || (x' <= 0)) && (!(x <= 0) || ( <= 0))) = 0 -> no errors diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_crypto.sol b/test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_crypto.sol index 627f79763..2a79e6c4d 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_crypto.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_crypto.sol @@ -25,8 +25,8 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreInv: yes // ---- // Warning 1218: (302-333): CHC: Error trying to invoke SMT solver. // Warning 6328: (302-333): CHC: Assertion violation might happen here. -// Info 1180: Contract invariant(s) for :C:\n(((kec + ((- 1) * keccak256(data))) >= 0) && ((kec + ((- 1) * keccak256(data))) <= 0))\nReentrancy property(ies) for :C:\n((!((kec + ((- 1) * keccak256(data))) >= 0) || ((kec' + ((- 1) * keccak256(data'))) >= 0)) && (!((kec + ((- 1) * keccak256(data))) <= 0) || ((kec' + ((- 1) * keccak256(data'))) <= 0)))\n((!( = 1) || !((kec + ((- 1) * keccak256(data))) = 0)) && (!((kec + ((- 1) * keccak256(data))) <= 0) || ((kec' + ((- 1) * keccak256(data'))) <= 0)) && (!((kec + ((- 1) * keccak256(data))) >= 0) || ((kec' + ((- 1) * keccak256(data'))) >= 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(_kec == kec)\n = 2 -> Assertion failed at assert(kec == keccak256(_data))\n // Warning 4661: (302-333): BMC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_1.sol b/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_1.sol index 1f05d1176..0fd508602 100644 --- a/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_1.sol +++ b/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_1.sol @@ -15,5 +15,5 @@ contract C is B { // ==== // SMTEngine: all // ---- -// 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\nState: y = 0, x = 1\nB.f() +// 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 // Info 1180: Contract invariant(s) for :B:\n(x <= 0)\n diff --git a/test/libsolidity/smtCheckerTests/inheritance/implicit_constructor_hierarchy.sol b/test/libsolidity/smtCheckerTests/inheritance/implicit_constructor_hierarchy.sol index 59d042302..c8b2f96c5 100644 --- a/test/libsolidity/smtCheckerTests/inheritance/implicit_constructor_hierarchy.sol +++ b/test/libsolidity/smtCheckerTests/inheritance/implicit_constructor_hierarchy.sol @@ -15,5 +15,4 @@ contract C is B { // ==== // SMTEngine: all // SMTSolvers: z3 -// ---- -// Info 1180: Contract invariant(s) for :C:\n(!(x <= 1) && !(x >= 3))\n +// SMTIgnoreInv: yes diff --git a/test/libsolidity/smtCheckerTests/operators/conditional_assignment_5.sol b/test/libsolidity/smtCheckerTests/operators/conditional_assignment_5.sol index 24be3cd8e..dd467f853 100644 --- a/test/libsolidity/smtCheckerTests/operators/conditional_assignment_5.sol +++ b/test/libsolidity/smtCheckerTests/operators/conditional_assignment_5.sol @@ -25,4 +25,6 @@ contract C { // SMTIgnoreCex: yes // ---- // Warning 2072: (249-255): Unused local variable. -// Warning 6328: (271-295): CHC: Assertion violation happens here. +// Warning 1218: (271-295): CHC: Error trying to invoke SMT solver. +// Warning 6328: (271-295): CHC: Assertion violation might happen here. +// Warning 4661: (271-295): BMC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/operators/conditional_assignment_6.sol b/test/libsolidity/smtCheckerTests/operators/conditional_assignment_6.sol index e37d3f84c..3b89e1afb 100644 --- a/test/libsolidity/smtCheckerTests/operators/conditional_assignment_6.sol +++ b/test/libsolidity/smtCheckerTests/operators/conditional_assignment_6.sol @@ -25,4 +25,4 @@ contract C { // SMTIgnoreOS: macos // ---- // Warning 2072: (255-261): Unused local variable. -// Info 1180: Reentrancy property(ies) for :C:\n((!(x <= 2) || !(x' >= 3)) && ( <= 0) && (!(x' <= 0) || !(x >= 2)))\n((!(x' <= 0) || ((x' + ((- 1) * x)) = 0)) && ( <= 0) && (!(x' >= 3) || ((x' + ((- 1) * x)) = 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(x == 2 || x == 1)\n +// Info 1180: Reentrancy property(ies) for :C:\n((!(x' <= 0) || ((x' + ((- 1) * x)) = 0)) && ( <= 0) && (!(x' >= 3) || ((x' + ((- 1) * x)) = 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(x == 2 || x == 1)\n From b2c9b69de2292c0a7c05bdc3cae6fcfe46d86383 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Fri, 13 Aug 2021 00:37:23 +0200 Subject: [PATCH 21/69] Enable for IR code generation with stack optimization > homestead. --- libyul/AssemblyStack.h | 4 +-- libyul/backends/evm/EVMObjectCompiler.cpp | 41 ++++++++++++++--------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/libyul/AssemblyStack.h b/libyul/AssemblyStack.h index 950265ca4..743d76dc6 100644 --- a/libyul/AssemblyStack.h +++ b/libyul/AssemblyStack.h @@ -139,9 +139,9 @@ public: private: bool analyzeParsed(); bool analyzeParsed(yul::Object& _object); - +public: void compileEVM(yul::AbstractAssembly& _assembly, bool _optimize) const; - +private: void optimize(yul::Object& _object, bool _isCreation); Language m_language = Language::Assembly; diff --git a/libyul/backends/evm/EVMObjectCompiler.cpp b/libyul/backends/evm/EVMObjectCompiler.cpp index e41a68387..c85c1ae92 100644 --- a/libyul/backends/evm/EVMObjectCompiler.cpp +++ b/libyul/backends/evm/EVMObjectCompiler.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -62,19 +63,29 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize) yulAssert(_object.analysisInfo, "No analysis info."); yulAssert(_object.code, "No code."); - // We do not catch and re-throw the stack too deep exception here because it is a YulException, - // which should be native to this part of the code. - CodeTransform transform{ - m_assembly, - *_object.analysisInfo, - *_object.code, - m_dialect, - context, - _optimize, - {}, - CodeTransform::UseNamedLabels::ForFirstFunctionOfEachName - }; - transform(*_object.code); - if (!transform.stackErrors().empty()) - BOOST_THROW_EXCEPTION(transform.stackErrors().front()); + if (_optimize && m_dialect.evmVersion().canOverchargeGasForCall()) + { + + auto stackErrors = OptimizedEVMCodeTransform::run(m_assembly, *_object.analysisInfo, *_object.code, m_dialect, context); + if (!stackErrors.empty()) + BOOST_THROW_EXCEPTION(stackErrors.front()); + } + else + { + // We do not catch and re-throw the stack too deep exception here because it is a YulException, + // which should be native to this part of the code. + CodeTransform transform{ + m_assembly, + *_object.analysisInfo, + *_object.code, + m_dialect, + context, + _optimize, + {}, + CodeTransform::UseNamedLabels::ForFirstFunctionOfEachName + }; + transform(*_object.code); + if (!transform.stackErrors().empty()) + BOOST_THROW_EXCEPTION(transform.stackErrors().front()); + } } From 4229369180d2ba0001aa1d4254eb188703d59ff8 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Thu, 12 Aug 2021 17:17:21 +0200 Subject: [PATCH 22/69] Compatibility with StackCompressor and StackLimitEvader. --- libsolidity/codegen/ir/IRGenerator.cpp | 3 - libyul/optimiser/StackCompressor.cpp | 130 ++++++++++++++++++++----- libyul/optimiser/StackLimitEvader.cpp | 43 ++++++++ libyul/optimiser/StackLimitEvader.h | 20 ++++ libyul/optimiser/Suite.cpp | 38 +++++--- 5 files changed, 193 insertions(+), 41 deletions(-) diff --git a/libsolidity/codegen/ir/IRGenerator.cpp b/libsolidity/codegen/ir/IRGenerator.cpp index b17b33c03..c2bb0c3cf 100644 --- a/libsolidity/codegen/ir/IRGenerator.cpp +++ b/libsolidity/codegen/ir/IRGenerator.cpp @@ -1069,9 +1069,6 @@ string IRGenerator::dispatchRoutine(ContractDefinition const& _contract) string IRGenerator::memoryInit(bool _useMemoryGuard) { - // TODO: Remove once we have made sure it is safe, i.e. after "Yul memory objects lite". - // Also restore the tests removed in the commit that adds this comment. - _useMemoryGuard = false; // This function should be called at the beginning of the EVM call frame // and thus can assume all memory to be zero, including the contents of // the "zero memory area" (the position CompilerUtils::zeroPointer points to). diff --git a/libyul/optimiser/StackCompressor.cpp b/libyul/optimiser/StackCompressor.cpp index a57d9738b..2deef5234 100644 --- a/libyul/optimiser/StackCompressor.cpp +++ b/libyul/optimiser/StackCompressor.cpp @@ -27,6 +27,13 @@ #include #include +#include +#include +#include + +#include +#include + #include #include @@ -162,6 +169,50 @@ void eliminateVariables( UnusedPruner::runUntilStabilised(_dialect, _node, _allowMSizeOptimization); } +void eliminateVariables( + Dialect const& _dialect, + Block& _block, + vector const& _unreachables, + bool _allowMSizeOptimization +) +{ + RematCandidateSelector selector{_dialect}; + selector(_block); + std::map candidates; + for (auto [cost, candidatesWithCost]: selector.candidates()) + for (auto candidate: candidatesWithCost) + candidates[get<0>(candidate)] = cost; + + set varsToEliminate; + + // TODO: this currently ignores the fact that variables may reference other variables we want to eliminate. + for (auto const& unreachable: _unreachables) + { + map> suitableCandidates; + size_t neededSlots = unreachable.deficit; + for (auto varName: unreachable.variableChoices) + { + if (varsToEliminate.count(varName)) + --neededSlots; + else if (size_t* cost = util::valueOrNullptr(candidates, varName)) + if (!util::contains(suitableCandidates[*cost], varName)) + suitableCandidates[*cost].emplace_back(varName); + } + for (auto candidatesByCost: suitableCandidates) + { + for (auto candidate: candidatesByCost.second) + if (neededSlots--) + varsToEliminate.emplace(candidate); + else + break; + if (!neededSlots) + break; + } + } + Rematerialiser::run(_dialect, _block, std::move(varsToEliminate), true); + UnusedPruner::runUntilStabilised(_dialect, _block, _allowMSizeOptimization); +} + } bool StackCompressor::run( @@ -176,39 +227,66 @@ bool StackCompressor::run( _object.code->statements.size() > 0 && holds_alternative(_object.code->statements.at(0)), "Need to run the function grouper before the stack compressor." ); + bool usesOptimizedCodeGenerator = false; + if (auto evmDialect = dynamic_cast(&_dialect)) + usesOptimizedCodeGenerator = + _optimizeStackAllocation && + evmDialect->evmVersion().canOverchargeGasForCall() && + evmDialect->providesObjectAccess(); bool allowMSizeOptimzation = !MSizeFinder::containsMSize(_dialect, *_object.code); - for (size_t iterations = 0; iterations < _maxIterations; iterations++) + if (usesOptimizedCodeGenerator) { - map stackSurplus = CompilabilityChecker(_dialect, _object, _optimizeStackAllocation).stackDeficit; - if (stackSurplus.empty()) - return true; - - if (stackSurplus.count(YulString{})) - { - yulAssert(stackSurplus.at({}) > 0, "Invalid surplus value."); - eliminateVariables( - _dialect, - std::get(_object.code->statements.at(0)), - static_cast(stackSurplus.at({})), - allowMSizeOptimzation - ); - } - + yul::AsmAnalysisInfo analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect(_dialect, _object); + unique_ptr cfg = ControlFlowGraphBuilder::build(analysisInfo, _dialect, *_object.code); + Block& mainBlock = std::get(_object.code->statements.at(0)); + if ( + auto stackTooDeepErrors = StackLayoutGenerator::reportStackTooDeep(*cfg, YulString{}); + !stackTooDeepErrors.empty() + ) + eliminateVariables(_dialect, mainBlock, stackTooDeepErrors, allowMSizeOptimzation); for (size_t i = 1; i < _object.code->statements.size(); ++i) { auto& fun = std::get(_object.code->statements[i]); - if (!stackSurplus.count(fun.name)) - continue; - - yulAssert(stackSurplus.at(fun.name) > 0, "Invalid surplus value."); - eliminateVariables( - _dialect, - fun, - static_cast(stackSurplus.at(fun.name)), - allowMSizeOptimzation - ); + if ( + auto stackTooDeepErrors = StackLayoutGenerator::reportStackTooDeep(*cfg, fun.name); + !stackTooDeepErrors.empty() + ) + eliminateVariables(_dialect, fun.body, stackTooDeepErrors, allowMSizeOptimzation); } } + else + for (size_t iterations = 0; iterations < _maxIterations; iterations++) + { + map stackSurplus = CompilabilityChecker(_dialect, _object, _optimizeStackAllocation).stackDeficit; + if (stackSurplus.empty()) + return true; + + if (stackSurplus.count(YulString{})) + { + yulAssert(stackSurplus.at({}) > 0, "Invalid surplus value."); + eliminateVariables( + _dialect, + std::get(_object.code->statements.at(0)), + static_cast(stackSurplus.at({})), + allowMSizeOptimzation + ); + } + + for (size_t i = 1; i < _object.code->statements.size(); ++i) + { + auto& fun = std::get(_object.code->statements[i]); + if (!stackSurplus.count(fun.name)) + continue; + + yulAssert(stackSurplus.at(fun.name) > 0, "Invalid surplus value."); + eliminateVariables( + _dialect, + fun, + static_cast(stackSurplus.at(fun.name)), + allowMSizeOptimzation + ); + } + } return false; } diff --git a/libyul/optimiser/StackLimitEvader.cpp b/libyul/optimiser/StackLimitEvader.cpp index 1c7903b1f..b77bd4f38 100644 --- a/libyul/optimiser/StackLimitEvader.cpp +++ b/libyul/optimiser/StackLimitEvader.cpp @@ -21,14 +21,18 @@ #include #include #include +#include #include +#include #include +#include #include #include #include #include #include +#include #include #include @@ -114,6 +118,45 @@ u256 literalArgumentValue(FunctionCall const& _call) } } +void StackLimitEvader::run( + OptimiserStepContext& _context, + Object& _object +) +{ + auto const* evmDialect = dynamic_cast(&_context.dialect); + yulAssert( + evmDialect && evmDialect->providesObjectAccess(), + "StackLimitEvader can only be run on objects using the EVMDialect with object access." + ); + if (evmDialect && evmDialect->evmVersion().canOverchargeGasForCall()) + { + yul::AsmAnalysisInfo analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect(*evmDialect, _object); + unique_ptr cfg = ControlFlowGraphBuilder::build(analysisInfo, *evmDialect, *_object.code); + run(_context, _object, StackLayoutGenerator::reportStackTooDeep(*cfg)); + } + else + run(_context, _object, CompilabilityChecker{ + _context.dialect, + _object, + true + }.unreachableVariables); + +} + +void StackLimitEvader::run( + OptimiserStepContext& _context, + Object& _object, + map> const& _stackTooDeepErrors +) +{ + map> unreachableVariables; + for (auto&& [function, stackTooDeepErrors]: _stackTooDeepErrors) + // TODO: choose wisely. + for (auto const& stackTooDeepError: stackTooDeepErrors) + unreachableVariables[function] += stackTooDeepError.variableChoices | ranges::views::take(stackTooDeepError.deficit) | ranges::to>; + run(_context, _object, unreachableVariables); +} + void StackLimitEvader::run( OptimiserStepContext& _context, Object& _object, diff --git a/libyul/optimiser/StackLimitEvader.h b/libyul/optimiser/StackLimitEvader.h index 4fc351f73..ae2d31c37 100644 --- a/libyul/optimiser/StackLimitEvader.h +++ b/libyul/optimiser/StackLimitEvader.h @@ -22,6 +22,7 @@ #pragma once #include +#include namespace solidity::yul { @@ -61,6 +62,25 @@ public: Object& _object, std::map> const& _unreachableVariables ); + /// @a _stackTooDeepErrors can be determined by the StackLayoutGenerator. + /// Can only be run on the EVM dialect with objects. + /// Abort and do nothing, if no ``memoryguard`` call or several ``memoryguard`` calls + /// with non-matching arguments are found, or if any of the @a _stackTooDeepErrors + /// are contained in a recursive function. + static void run( + OptimiserStepContext& _context, + Object& _object, + std::map> const& _stackTooDeepErrors + ); + /// Determines stack too deep errors using the appropriate code generation backend. + /// Can only be run on the EVM dialect with objects. + /// Abort and do nothing, if no ``memoryguard`` call or several ``memoryguard`` calls + /// with non-matching arguments are found, or if any of the unreachable variables + /// are contained in a recursive function. + static void run( + OptimiserStepContext& _context, + Object& _object + ); }; } diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index 5525e17d2..bd81f7c0b 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -95,6 +95,12 @@ void OptimiserSuite::run( set const& _externallyUsedIdentifiers ) { + EVMDialect const* evmDialect = dynamic_cast(&_dialect); + bool usesOptimizedCodeGenerator = + _optimizeStackAllocation && + evmDialect && + evmDialect->evmVersion().canOverchargeGasForCall() && + evmDialect->providesObjectAccess(); set reservedIdentifiers = _externallyUsedIdentifiers; reservedIdentifiers += _dialect.fixedFunctionNames(); @@ -121,24 +127,32 @@ void OptimiserSuite::run( // We ignore the return value because we will get a much better error // message once we perform code generation. - StackCompressor::run( - _dialect, - _object, - _optimizeStackAllocation, - stackCompressorMaxIterations - ); + if (!usesOptimizedCodeGenerator) + StackCompressor::run( + _dialect, + _object, + _optimizeStackAllocation, + stackCompressorMaxIterations + ); suite.runSequence("fDnTOc g", ast); - if (EVMDialect const* dialect = dynamic_cast(&_dialect)) + if (evmDialect) { yulAssert(_meter, ""); - ConstantOptimiser{*dialect, *_meter}(ast); - if (dialect->providesObjectAccess() && _optimizeStackAllocation) - StackLimitEvader::run(suite.m_context, _object, CompilabilityChecker{ + ConstantOptimiser{*evmDialect, *_meter}(ast); + if (usesOptimizedCodeGenerator) + { + StackCompressor::run( _dialect, _object, - _optimizeStackAllocation - }.unreachableVariables); + _optimizeStackAllocation, + stackCompressorMaxIterations + ); + if (evmDialect->providesObjectAccess()) + StackLimitEvader::run(suite.m_context, _object); + } + else if (evmDialect->providesObjectAccess() && _optimizeStackAllocation) + StackLimitEvader::run(suite.m_context, _object); } else if (dynamic_cast(&_dialect)) { From 1a0605c5940b769179667ca9c2b858c0d6502b17 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Wed, 15 Sep 2021 17:01:40 +0200 Subject: [PATCH 23/69] Update tests. --- libyul/AssemblyStack.h | 4 +- .../output | 26 +- .../output | 26 +- .../output | 26 +- .../debug_info_in_yul_snippet_escaping/output | 68 +- test/cmdlineTests/exp_base_literal/output | 4 +- .../function_debug_info_via_yul/output | 15 +- .../output | 22 +- .../ir_compiler_subobjects/output | 61 +- .../output | 13 +- .../output | 9 +- .../keccak_optimization_low_runs/output | 9 +- test/cmdlineTests/name_simplifier/output | 11 +- test/cmdlineTests/object_compiler/output | 6 +- .../cmdlineTests/optimizer_array_sload/output | 11 +- test/cmdlineTests/revert_strings/output | 4 +- .../output.json | 1198 +++++++++-------- .../output.json | 26 +- .../output.json | 26 +- .../output.json | 26 +- .../output.json | 58 +- .../standard_ewasm_requested/output.json | 18 +- .../output.json | 4 +- .../standard_ir_requested/output.json | 4 +- .../standard_viair_requested/output.json | 12 +- .../standard_yul_optimiserSteps/output.json | 4 +- .../standard_yul_optimized/output.json | 4 +- .../standard_yul_stack_opt/output.json | 6 +- .../strict_asm_optimizer_steps/output | 21 +- test/cmdlineTests/viair_abicoder_v1/output | 4 +- test/cmdlineTests/viair_subobjects/output | 61 +- test/cmdlineTests/yul_optimize_runs/output | 8 +- test/cmdlineTests/yul_optimizer_steps/output | 4 +- .../output | 4 +- .../yul_string_format_ascii/output.json | 4 +- .../output.json | 4 +- .../output.json | 4 +- .../yul_string_format_ascii_long/output.json | 4 +- .../yul_string_format_hex/output.json | 4 +- test/cmdlineTests/yul_verbatim_msize/output | 4 +- .../abiEncoderV1/abi_decode_v2_storage.sol | 2 +- .../abi_encode_calldata_slice.sol | 4 +- .../struct/struct_storage_ptr.sol | 2 +- .../abi_encode_calldata_slice.sol | 4 +- .../abiEncoderV2/abi_encode_v2.sol | 2 +- ...2_in_function_inherited_in_v1_contract.sol | 2 +- ...ode_v2_in_modifier_used_in_v1_contract.sol | 2 +- .../abiEncoderV2/calldata_array.sol | 2 +- .../abiEncoderV2/storage_array_encoding.sol | 4 +- .../abi_decode_simple_storage.sol | 2 +- .../arrays_complex_from_and_to_storage.sol | 2 +- .../array/byte_array_storage_layout.sol | 2 +- .../array/byte_array_transitional_2.sol | 2 +- .../array/bytes_length_member.sol | 2 +- .../copying/array_copy_calldata_storage.sol | 2 +- .../copying/array_copy_cleanup_uint128.sol | 2 +- .../copying/array_copy_cleanup_uint40.sol | 2 +- .../copying/array_copy_clear_storage.sol | 2 +- .../array_copy_clear_storage_packed.sol | 4 +- .../copying/array_copy_different_packing.sol | 2 +- .../copying/array_copy_including_array.sol | 4 +- .../array/copying/array_copy_nested_array.sol | 2 +- ...ay_copy_storage_storage_different_base.sol | 2 +- ..._storage_storage_different_base_nested.sol | 2 +- .../array_copy_storage_storage_dyn_dyn.sol | 2 +- ...y_copy_storage_storage_dynamic_dynamic.sol | 2 +- ...ay_copy_storage_storage_static_dynamic.sol | 2 +- ...ray_copy_storage_storage_static_static.sol | 2 +- .../array_copy_storage_storage_struct.sol | 2 +- .../array_copy_storage_to_memory_nested.sol | 2 +- .../copying/array_copy_target_leftover.sol | 2 +- .../copying/array_copy_target_leftover2.sol | 2 +- .../copying/array_copy_target_simple.sol | 2 +- .../copying/array_copy_target_simple_2.sol | 2 +- .../array_nested_calldata_to_storage.sol | 8 +- .../array_nested_memory_to_storage.sol | 4 +- .../array_of_struct_calldata_to_storage.sol | 2 +- .../array_of_struct_memory_to_storage.sol | 2 +- ..._containing_arrays_calldata_to_storage.sol | 2 +- ...ts_containing_arrays_memory_to_storage.sol | 2 +- .../array_storage_multi_items_per_slot.sol | 2 +- .../copying/arrays_from_and_to_storage.sol | 2 +- .../array/copying/bytes_inside_mappings.sol | 4 +- .../copying/bytes_storage_to_storage.sol | 10 +- .../calldata_array_dynamic_to_storage.sol | 2 +- .../copy_byte_array_in_struct_to_storage.sol | 4 +- .../copying/copy_byte_array_to_storage.sol | 2 +- .../copying/copy_function_storage_array.sol | 2 +- .../array/copying/copy_removes_bytes_data.sol | 2 +- .../memory_dyn_2d_bytes_to_storage.sol | 2 +- .../array/copying/storage_memory_nested.sol | 2 +- .../copying/storage_memory_nested_bytes.sol | 2 +- .../storage_memory_nested_from_pointer.sol | 2 +- .../copying/storage_memory_nested_struct.sol | 2 +- .../copying/storage_memory_packed_dyn.sol | 2 +- .../array/create_memory_array.sol | 2 +- .../array/delete/bytes_delete_element.sol | 2 +- .../delete/delete_storage_array_packed.sol | 2 +- .../array/dynamic_array_cleanup.sol | 2 +- .../array/dynamic_arrays_in_storage.sol | 2 +- .../array/dynamic_multi_array_cleanup.sol | 2 +- .../array/fixed_array_cleanup.sol | 2 +- .../array/fixed_arrays_as_return_type.sol | 2 +- .../array/function_array_cross_calls.sol | 2 +- .../array/pop/array_pop_array_transition.sol | 2 +- .../array/pop/array_pop_uint16_transition.sol | 2 +- .../array/pop/array_pop_uint24_transition.sol | 2 +- .../array/pop/byte_array_pop_copy_long.sol | 2 +- .../pop/byte_array_pop_long_storage_empty.sol | 2 +- ...ray_pop_long_storage_empty_garbage_ref.sol | 2 +- .../array/pop/byte_array_pop_masking_long.sol | 2 +- .../semanticTests/array/push/array_push.sol | 2 +- .../push/array_push_nested_from_calldata.sol | 2 +- .../array/push/array_push_packed_array.sol | 2 +- .../array/push/array_push_struct.sol | 2 +- .../push/array_push_struct_from_calldata.sol | 2 +- .../array/push/byte_array_push_transition.sol | 2 +- .../array/push/nested_bytes_push.sol | 2 +- .../array/push/push_no_args_2d.sol | 4 +- .../array/push/push_no_args_bytes.sol | 2 +- .../semanticTests/array/reusing_memory.sol | 2 +- .../constructor/arrays_in_constructors.sol | 2 +- .../bytes_in_constructors_packer.sol | 2 +- .../constructor/no_callvalue_check.sol | 2 +- .../events/event_dynamic_array_storage.sol | 2 +- .../events/event_dynamic_array_storage_v2.sol | 2 +- .../event_dynamic_nested_array_storage_v2.sol | 2 +- .../events/event_indexed_mixed.sol | 2 +- .../events/event_indexed_string.sol | 2 +- .../externalContracts/FixedFeeRegistrar.sol | 6 +- .../externalContracts/deposit_contract.sol | 10 +- .../externalContracts/prbmath_signed.sol | 22 +- .../externalContracts/prbmath_unsigned.sol | 22 +- .../externalContracts/ramanujan_pi.sol | 4 +- .../semanticTests/externalContracts/snark.sol | 2 +- .../externalContracts/strings.sol | 12 +- .../functionCall/failed_create.sol | 4 +- .../mapping_array_internal_argument.sol | 2 +- .../functionTypes/store_function.sol | 2 +- .../immutable/multi_creation.sol | 2 +- .../address_overload_resolution.sol | 4 +- ...d_function_calldata_calldata_interface.sol | 2 +- ...ted_function_calldata_memory_interface.sol | 2 +- .../keccak_yul_optimization.sol | 4 +- .../interface_inheritance_conversions.sol | 6 +- .../salted_create/salted_create.sol | 2 +- .../salted_create_with_value.sol | 2 +- .../storage/packed_storage_structs_bytes.sol | 2 +- ...ta_struct_with_nested_array_to_storage.sol | 2 +- .../conversion/recursive_storage_memory.sol | 2 +- .../structs/memory_structs_nested_load.sol | 2 +- ...truct_containing_bytes_copy_and_delete.sol | 2 +- .../semanticTests/structs/struct_copy.sol | 4 +- .../structs/struct_copy_via_local.sol | 2 +- .../struct_delete_storage_nested_small.sol | 2 +- .../struct_delete_storage_with_array.sol | 2 +- ...truct_delete_storage_with_arrays_small.sol | 2 +- .../struct_memory_to_storage_function_ptr.sol | 2 +- .../semanticTests/structs/structs.sol | 2 +- .../userDefinedValueType/calldata.sol | 4 +- .../calldata_to_storage.sol | 6 +- .../userDefinedValueType/erc20.sol | 14 +- .../memory_to_storage.sol | 6 +- ...cost_abstraction_comparison_elementary.sol | 8 +- ...ost_abstraction_comparison_userdefined.sol | 8 +- .../various/destructuring_assignment.sol | 2 +- .../semanticTests/various/erc20.sol | 14 +- .../skip_dynamic_types_for_structs.sol | 2 +- .../various/staticcall_for_view_and_pure.sol | 4 +- .../various/swap_in_storage_overwrite.sol | 2 +- .../viaYul/array_memory_index_access.sol | 2 +- .../viaYul/array_storage_index_access.sol | 16 +- .../array_storage_index_boundary_test.sol | 4 +- .../array_storage_index_zeroed_test.sol | 8 +- .../viaYul/array_storage_length_access.sol | 4 +- .../viaYul/array_storage_push_empty.sol | 4 +- ...rray_storage_push_empty_length_address.sol | 6 +- .../viaYul/array_storage_push_pop.sol | 6 +- test/libyul/EVMCodeTransformTest.cpp | 17 +- .../early_push_on_deep_swap.yul | 54 + test/libyul/evmCodeTransform/literal_loop.yul | 74 + .../nonempty_initial_layout.yul | 17 + .../evmCodeTransform/stackReuse/for_1.yul | 27 +- .../evmCodeTransform/stackReuse/for_2.yul | 34 +- .../stackReuse/function_argument_reuse.yul | 42 +- ...ction_argument_reuse_without_retparams.yul | 48 +- .../stackReuse/function_call.yul | 57 +- .../stackReuse/function_many_arguments.yul | 172 ++- .../stackReuse/function_params.yul | 15 +- .../function_params_and_retparams.yul | 29 +- ...ction_params_and_retparams_partly_used.yul | 53 +- .../stackReuse/function_retparam.yul | 21 +- .../stackReuse/function_retparam_block.yul | 30 +- .../function_retparam_declaration.yul | 29 +- .../stackReuse/function_retparam_for.yul | 39 +- .../stackReuse/function_retparam_if.yul | 46 +- .../stackReuse/function_retparam_leave.yul | 28 +- .../stackReuse/function_retparam_read.yul | 39 +- .../function_retparam_unassigned.yul | 24 +- .../function_retparam_unassigned_multiple.yul | 32 +- .../stackReuse/function_trivial.yul | 11 +- .../function_with_body_embedded.yul | 43 +- .../stackReuse/functions_multi_return.yul | 107 +- .../libyul/evmCodeTransform/stackReuse/if.yul | 31 +- .../stackReuse/last_use_in_nested_block.yul | 14 +- .../multi_reuse_same_variable_name.yul | 41 +- .../stackReuse/multi_reuse_single_slot.yul | 26 +- .../multi_reuse_single_slot_nested.yul | 26 +- .../reuse_on_decl_assign_not_same_scope.yul | 14 +- .../reuse_on_decl_assign_to_last_used.yul | 15 +- ...reuse_on_decl_assign_to_last_used_expr.yul | 21 +- .../reuse_on_decl_assign_to_not_last_used.yul | 15 +- .../stackReuse/reuse_slots.yul | 42 +- .../stackReuse/reuse_slots_function.yul | 69 +- .../reuse_slots_function_with_gaps.yul | 77 +- .../stackReuse/reuse_too_deep_slot.yul | 180 +-- .../stackReuse/single_var.yul | 6 +- .../stackReuse/single_var_assigned.yul | 6 +- .../single_var_assigned_plus_code.yul | 17 +- ...ngle_var_assigned_plus_code_and_reused.yul | 22 +- .../evmCodeTransform/stackReuse/smoke.yul | 2 + .../evmCodeTransform/stackReuse/switch.yul | 53 +- test/libyul/evmCodeTransform/stub.yul | 86 ++ .../objectCompiler/long_object_name.yul | 10 +- .../objectCompiler/nested_optimizer.yul | 14 +- .../objectCompiler/simple_optimizer.yul | 10 +- .../yulOptimizerTests/fullSuite/aztec.yul | 90 +- .../fullSuite/stack_compressor_msize.yul | 29 +- .../stackCompressor/inlineInBlock.yul | 2 + .../stackCompressor/inlineInFunction.yul | 2 + .../stackCompressor/unusedPrunerWithMSize.yul | 2 + test/libyul/yulStackLayout/literal_loop.yul | 69 + 232 files changed, 2473 insertions(+), 1899 deletions(-) create mode 100644 test/libyul/evmCodeTransform/early_push_on_deep_swap.yul create mode 100644 test/libyul/evmCodeTransform/literal_loop.yul create mode 100644 test/libyul/evmCodeTransform/nonempty_initial_layout.yul create mode 100644 test/libyul/evmCodeTransform/stub.yul create mode 100644 test/libyul/yulStackLayout/literal_loop.yul diff --git a/libyul/AssemblyStack.h b/libyul/AssemblyStack.h index 743d76dc6..950265ca4 100644 --- a/libyul/AssemblyStack.h +++ b/libyul/AssemblyStack.h @@ -139,9 +139,9 @@ public: private: bool analyzeParsed(); bool analyzeParsed(yul::Object& _object); -public: + void compileEVM(yul::AbstractAssembly& _assembly, bool _optimize) const; -private: + void optimize(yul::Object& _object, bool _isCreation); Language m_language = Language::Assembly; diff --git a/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_all/output b/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_all/output index 31b0ae463..1b90e94a3 100644 --- a/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_all/output +++ b/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_all/output @@ -66,7 +66,7 @@ IR: object "C_6" { code { /// @src 0:60:101 "contract C {..." - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_6() @@ -97,7 +97,7 @@ object "C_6" { object "C_6_deployed" { code { /// @src 0:60:101 "contract C {..." - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { @@ -182,11 +182,12 @@ object "C_6" { code { { /// @src 0:60:101 "contract C {..." - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("C_6_deployed") - codecopy(128, dataoffset("C_6_deployed"), _1) - return(128, _1) + let _2 := datasize("C_6_deployed") + codecopy(_1, dataoffset("C_6_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"debug_info_in_yul_and_evm_asm_print_all/input.sol" @@ -194,15 +195,16 @@ object "C_6" { code { { /// @src 0:60:101 "contract C {..." - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if iszero(lt(calldatasize(), 4)) { - let _1 := 0 - if eq(0x26121ff0, shr(224, calldataload(_1))) + let _2 := 0 + if eq(0x26121ff0, shr(224, calldataload(_2))) { - if callvalue() { revert(_1, _1) } - if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) } - return(128, _1) + if callvalue() { revert(_2, _2) } + if slt(add(calldatasize(), not(3)), _2) { revert(_2, _2) } + return(_1, _2) } } revert(0, 0) diff --git a/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_location_only/output b/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_location_only/output index 4d7210d37..86968e71b 100644 --- a/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_location_only/output +++ b/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_location_only/output @@ -66,7 +66,7 @@ IR: object "C_6" { code { /// @src 0:60:101 - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_6() @@ -97,7 +97,7 @@ object "C_6" { object "C_6_deployed" { code { /// @src 0:60:101 - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { @@ -181,11 +181,12 @@ object "C_6" { code { { /// @src 0:60:101 - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("C_6_deployed") - codecopy(128, dataoffset("C_6_deployed"), _1) - return(128, _1) + let _2 := datasize("C_6_deployed") + codecopy(_1, dataoffset("C_6_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"debug_info_in_yul_and_evm_asm_print_location_only/input.sol" @@ -193,15 +194,16 @@ object "C_6" { code { { /// @src 0:60:101 - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if iszero(lt(calldatasize(), 4)) { - let _1 := 0 - if eq(0x26121ff0, shr(224, calldataload(_1))) + let _2 := 0 + if eq(0x26121ff0, shr(224, calldataload(_2))) { - if callvalue() { revert(_1, _1) } - if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) } - return(128, _1) + if callvalue() { revert(_2, _2) } + if slt(add(calldatasize(), not(3)), _2) { revert(_2, _2) } + return(_1, _2) } } revert(0, 0) diff --git a/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_none/output b/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_none/output index 0c0fbfa1e..6a87b0b46 100644 --- a/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_none/output +++ b/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_none/output @@ -63,7 +63,7 @@ IR: object "C_6" { code { - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_6() @@ -90,7 +90,7 @@ object "C_6" { object "C_6_deployed" { code { - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { @@ -171,26 +171,28 @@ Optimized IR: object "C_6" { code { { - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("C_6_deployed") - codecopy(128, dataoffset("C_6_deployed"), _1) - return(128, _1) + let _2 := datasize("C_6_deployed") + codecopy(_1, dataoffset("C_6_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"debug_info_in_yul_and_evm_asm_print_none/input.sol" object "C_6_deployed" { code { { - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if iszero(lt(calldatasize(), 4)) { - let _1 := 0 - if eq(0x26121ff0, shr(224, calldataload(_1))) + let _2 := 0 + if eq(0x26121ff0, shr(224, calldataload(_2))) { - if callvalue() { revert(_1, _1) } - if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) } - return(128, _1) + if callvalue() { revert(_2, _2) } + if slt(add(calldatasize(), not(3)), _2) { revert(_2, _2) } + return(_1, _2) } } revert(0, 0) diff --git a/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output b/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output index b595a771e..ae3ee1735 100644 --- a/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output +++ b/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output @@ -11,7 +11,7 @@ IR: object "C_2" { code { /// @src 0:265:278 "contract C {}" - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_2() @@ -42,7 +42,7 @@ object "C_2" { object "C_2_deployed" { code { /// @src 0:265:278 "contract C {}" - mstore(64, 128) + mstore(64, memoryguard(128)) revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() @@ -82,11 +82,12 @@ object "C_2" { code { { /// @src 0:265:278 "contract C {}" - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("C_2_deployed") - codecopy(128, dataoffset("C_2_deployed"), _1) - return(128, _1) + let _2 := datasize("C_2_deployed") + codecopy(_1, dataoffset("C_2_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"debug_info_in_yul_snippet_escaping/input.sol" @@ -94,7 +95,7 @@ object "C_2" { code { { /// @src 0:265:278 "contract C {}" - mstore(64, 128) + mstore(64, memoryguard(0x80)) revert(0, 0) } } @@ -115,7 +116,7 @@ IR: object "D_27" { code { /// @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_D_27() @@ -146,7 +147,7 @@ object "D_27" { object "D_27_deployed" { code { /// @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { @@ -372,7 +373,7 @@ object "D_27" { object "C_2" { code { /// @src 0:265:278 "contract C {}" - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_2() @@ -403,7 +404,7 @@ object "D_27" { object "C_2_deployed" { code { /// @src 0:265:278 "contract C {}" - mstore(64, 128) + mstore(64, memoryguard(128)) revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() @@ -448,11 +449,12 @@ object "D_27" { code { { /// @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("D_27_deployed") - codecopy(128, dataoffset("D_27_deployed"), _1) - return(128, _1) + let _2 := datasize("D_27_deployed") + codecopy(_1, dataoffset("D_27_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"debug_info_in_yul_snippet_escaping/input.sol" @@ -460,26 +462,25 @@ object "D_27" { code { { /// @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if iszero(lt(calldatasize(), 4)) { - let _1 := 0 - if eq(0x26121ff0, shr(224, calldataload(_1))) + let _2 := 0 + if eq(0x26121ff0, shr(224, calldataload(_2))) { - if callvalue() { revert(_1, _1) } - if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) } + if callvalue() { revert(_2, _2) } + if slt(add(calldatasize(), not(3)), _2) { revert(_2, _2) } /// @src 0:446:491 "new /// @src 0:149:156 \"new C()\"..." - let _2 := datasize("C_2") - let _3 := add(/** @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." */ 128, /** @src 0:446:491 "new /// @src 0:149:156 \"new C()\"..." */ _2) - if or(gt(_3, 0xffffffffffffffff), lt(_3, /** @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." */ 128)) - /// @src 0:446:491 "new /// @src 0:149:156 \"new C()\"..." - { panic_error_0x41() } - datacopy(/** @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." */ 128, /** @src 0:446:491 "new /// @src 0:149:156 \"new C()\"..." */ dataoffset("C_2"), _2) - if iszero(create(/** @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." */ _1, 128, /** @src 0:446:491 "new /// @src 0:149:156 \"new C()\"..." */ _2)) + let _3 := datasize("C_2") + let _4 := add(_1, _3) + if or(gt(_4, 0xffffffffffffffff), lt(_4, _1)) { panic_error_0x41() } + datacopy(_1, dataoffset("C_2"), _3) + if iszero(create(/** @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." */ _2, /** @src 0:446:491 "new /// @src 0:149:156 \"new C()\"..." */ _1, sub(_4, _1))) { /// @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." let pos := mload(64) - returndatacopy(pos, _1, returndatasize()) + returndatacopy(pos, _2, returndatasize()) revert(pos, returndatasize()) } mstore(add(allocate_memory_array_string(), 32), "/*") @@ -539,11 +540,12 @@ object "D_27" { code { { /// @src 0:265:278 "contract C {}" - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("C_2_deployed") - codecopy(128, dataoffset("C_2_deployed"), _1) - return(128, _1) + let _2 := datasize("C_2_deployed") + codecopy(_1, dataoffset("C_2_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"debug_info_in_yul_snippet_escaping/input.sol" @@ -551,7 +553,7 @@ object "D_27" { code { { /// @src 0:265:278 "contract C {}" - mstore(64, 128) + mstore(64, memoryguard(0x80)) revert(0, 0) } } diff --git a/test/cmdlineTests/exp_base_literal/output b/test/cmdlineTests/exp_base_literal/output index 9c3efdc1f..77893da18 100644 --- a/test/cmdlineTests/exp_base_literal/output +++ b/test/cmdlineTests/exp_base_literal/output @@ -11,7 +11,7 @@ IR: object "C_81" { code { /// @src 0:82:370 "contract C {..." - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_81() @@ -42,7 +42,7 @@ object "C_81" { object "C_81_deployed" { code { /// @src 0:82:370 "contract C {..." - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { diff --git a/test/cmdlineTests/function_debug_info_via_yul/output b/test/cmdlineTests/function_debug_info_via_yul/output index 8b952a9e9..5af245ce4 100644 --- a/test/cmdlineTests/function_debug_info_via_yul/output +++ b/test/cmdlineTests/function_debug_info_via_yul/output @@ -4,20 +4,7 @@ "function_debug_info_via_yul/input.sol:C": { "function-debug": {}, - "function-debug-runtime": - { - "abi_encode_uint256": - { - "parameterSlots": 2, - "returnSlots": 1 - }, - "calldata_array_index_access_uint256_dyn_calldata": - { - "entryPoint": 168, - "parameterSlots": 2, - "returnSlots": 1 - } - } + "function-debug-runtime": {} } }, "version": "" diff --git a/test/cmdlineTests/ir_compiler_inheritance_nosubobjects/output b/test/cmdlineTests/ir_compiler_inheritance_nosubobjects/output index 12c61e783..330e208f4 100644 --- a/test/cmdlineTests/ir_compiler_inheritance_nosubobjects/output +++ b/test/cmdlineTests/ir_compiler_inheritance_nosubobjects/output @@ -11,11 +11,12 @@ object "C_7" { code { { /// @src 0:82:117 "contract C {..." - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("C_7_deployed") - codecopy(128, dataoffset("C_7_deployed"), _1) - return(128, _1) + let _2 := datasize("C_7_deployed") + codecopy(_1, dataoffset("C_7_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"ir_compiler_inheritance_nosubobjects/input.sol" @@ -23,7 +24,7 @@ object "C_7" { code { { /// @src 0:82:117 "contract C {..." - mstore(64, 128) + mstore(64, memoryguard(0x80)) revert(0, 0) } } @@ -44,11 +45,12 @@ object "D_10" { code { { /// @src 0:118:137 "contract D is C {..." - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("D_10_deployed") - codecopy(128, dataoffset("D_10_deployed"), _1) - return(128, _1) + let _2 := datasize("D_10_deployed") + codecopy(_1, dataoffset("D_10_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"ir_compiler_inheritance_nosubobjects/input.sol" @@ -56,7 +58,7 @@ object "D_10" { code { { /// @src 0:118:137 "contract D is C {..." - mstore(64, 128) + mstore(64, memoryguard(0x80)) revert(0, 0) } } diff --git a/test/cmdlineTests/ir_compiler_subobjects/output b/test/cmdlineTests/ir_compiler_subobjects/output index 8c23c8ad7..fbedf38db 100644 --- a/test/cmdlineTests/ir_compiler_subobjects/output +++ b/test/cmdlineTests/ir_compiler_subobjects/output @@ -11,11 +11,12 @@ object "C_3" { code { { /// @src 0:82:95 "contract C {}" - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("C_3_deployed") - codecopy(128, dataoffset("C_3_deployed"), _1) - return(128, _1) + let _2 := datasize("C_3_deployed") + codecopy(_1, dataoffset("C_3_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"ir_compiler_subobjects/input.sol" @@ -23,7 +24,7 @@ object "C_3" { code { { /// @src 0:82:95 "contract C {}" - mstore(64, 128) + mstore(64, memoryguard(0x80)) revert(0, 0) } } @@ -44,11 +45,12 @@ object "D_16" { code { { /// @src 0:96:165 "contract D {..." - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("D_16_deployed") - codecopy(128, dataoffset("D_16_deployed"), _1) - return(128, _1) + let _2 := datasize("D_16_deployed") + codecopy(_1, dataoffset("D_16_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"ir_compiler_subobjects/input.sol" @@ -56,35 +58,35 @@ object "D_16" { code { { /// @src 0:96:165 "contract D {..." - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if iszero(lt(calldatasize(), 4)) { - let _1 := 0 - if eq(0x26121ff0, shr(224, calldataload(_1))) + let _2 := 0 + if eq(0x26121ff0, shr(224, calldataload(_2))) { - if callvalue() { revert(_1, _1) } - if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) } - /// @src 0:149:156 "new C()" - let _2 := datasize("C_3") - let _3 := add(/** @src 0:96:165 "contract D {..." */ 128, /** @src 0:149:156 "new C()" */ _2) - if or(gt(_3, 0xffffffffffffffff), lt(_3, /** @src 0:96:165 "contract D {..." */ 128)) + if callvalue() { revert(_2, _2) } + if slt(add(calldatasize(), not(3)), _2) { revert(_2, _2) } /// @src 0:149:156 "new C()" + let _3 := datasize("C_3") + let _4 := add(_1, _3) + if or(gt(_4, 0xffffffffffffffff), lt(_4, _1)) { /// @src 0:96:165 "contract D {..." - mstore(_1, shl(224, 0x4e487b71)) + mstore(_2, shl(224, 0x4e487b71)) mstore(4, 0x41) - revert(_1, 0x24) + revert(_2, 0x24) } /// @src 0:149:156 "new C()" - datacopy(/** @src 0:96:165 "contract D {..." */ 128, /** @src 0:149:156 "new C()" */ dataoffset("C_3"), _2) - if iszero(create(/** @src 0:96:165 "contract D {..." */ _1, 128, /** @src 0:149:156 "new C()" */ _2)) + datacopy(_1, dataoffset("C_3"), _3) + if iszero(create(/** @src 0:96:165 "contract D {..." */ _2, /** @src 0:149:156 "new C()" */ _1, sub(_4, _1))) { /// @src 0:96:165 "contract D {..." let pos := mload(64) - returndatacopy(pos, _1, returndatasize()) + returndatacopy(pos, _2, returndatasize()) revert(pos, returndatasize()) } - return(mload(64), _1) + return(mload(64), _2) } } revert(0, 0) @@ -95,11 +97,12 @@ object "D_16" { code { { /// @src 0:82:95 "contract C {}" - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("C_3_deployed") - codecopy(128, dataoffset("C_3_deployed"), _1) - return(128, _1) + let _2 := datasize("C_3_deployed") + codecopy(_1, dataoffset("C_3_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"ir_compiler_subobjects/input.sol" @@ -107,7 +110,7 @@ object "D_16" { code { { /// @src 0:82:95 "contract C {}" - mstore(64, 128) + mstore(64, memoryguard(0x80)) revert(0, 0) } } diff --git a/test/cmdlineTests/ir_with_assembly_no_memoryguard_creation/output b/test/cmdlineTests/ir_with_assembly_no_memoryguard_creation/output index 930899aea..34b72f8b8 100644 --- a/test/cmdlineTests/ir_with_assembly_no_memoryguard_creation/output +++ b/test/cmdlineTests/ir_with_assembly_no_memoryguard_creation/output @@ -23,15 +23,16 @@ object "D_12" { code { { /// @src 0:82:161 "contract D {..." - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if iszero(lt(calldatasize(), 4)) { - let _1 := 0 - if eq(0x26121ff0, shr(224, calldataload(_1))) + let _2 := 0 + if eq(0x26121ff0, shr(224, calldataload(_2))) { - if callvalue() { revert(_1, _1) } - if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) } - return(128, _1) + if callvalue() { revert(_2, _2) } + if slt(add(calldatasize(), not(3)), _2) { revert(_2, _2) } + return(_1, _2) } } revert(0, 0) diff --git a/test/cmdlineTests/ir_with_assembly_no_memoryguard_runtime/output b/test/cmdlineTests/ir_with_assembly_no_memoryguard_runtime/output index da6540fa7..cc95451e6 100644 --- a/test/cmdlineTests/ir_with_assembly_no_memoryguard_runtime/output +++ b/test/cmdlineTests/ir_with_assembly_no_memoryguard_runtime/output @@ -11,11 +11,12 @@ object "D_8" { code { { /// @src 0:82:153 "contract D {..." - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("D_8_deployed") - codecopy(128, dataoffset("D_8_deployed"), _1) - return(128, _1) + let _2 := datasize("D_8_deployed") + codecopy(_1, dataoffset("D_8_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"ir_with_assembly_no_memoryguard_runtime/input.sol" diff --git a/test/cmdlineTests/keccak_optimization_low_runs/output b/test/cmdlineTests/keccak_optimization_low_runs/output index 25b678ee0..f5df14027 100644 --- a/test/cmdlineTests/keccak_optimization_low_runs/output +++ b/test/cmdlineTests/keccak_optimization_low_runs/output @@ -11,11 +11,12 @@ object "C_7" { code { { /// @src 0:62:285 "contract C {..." - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("C_7_deployed") - codecopy(128, dataoffset("C_7_deployed"), _1) - return(128, _1) + let _2 := datasize("C_7_deployed") + codecopy(_1, dataoffset("C_7_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"keccak_optimization_low_runs/input.sol" diff --git a/test/cmdlineTests/name_simplifier/output b/test/cmdlineTests/name_simplifier/output index 44852d1a8..57a4cb594 100644 --- a/test/cmdlineTests/name_simplifier/output +++ b/test/cmdlineTests/name_simplifier/output @@ -11,11 +11,12 @@ object "C_59" { code { { /// @src 0:346:625 "contract C {..." - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("C_59_deployed") - codecopy(128, dataoffset("C_59_deployed"), _1) - return(128, _1) + let _2 := datasize("C_59_deployed") + codecopy(_1, dataoffset("C_59_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"name_simplifier/input.sol" @@ -23,7 +24,7 @@ object "C_59" { code { { /// @src 0:346:625 "contract C {..." - mstore(64, 128) + mstore(64, memoryguard(0x80)) if iszero(lt(calldatasize(), 4)) { let _1 := 0 diff --git a/test/cmdlineTests/object_compiler/output b/test/cmdlineTests/object_compiler/output index eb8a3286e..93d7b7795 100644 --- a/test/cmdlineTests/object_compiler/output +++ b/test/cmdlineTests/object_compiler/output @@ -23,7 +23,7 @@ object "MyContract" { Binary representation: -33600055600b806011600039806000f3fe60005460005260206000f3 +33600055600b8060106000396000f3fe60005460005260206000f3 Text representation: /* "object_compiler/input.yul":128:136 */ @@ -34,15 +34,13 @@ Text representation: sstore /* "object_compiler/input.yul":240:259 */ dataSize(sub_0) - dup1 /* "object_compiler/input.yul":217:238 */ + dup1 dataOffset(sub_0) /* "object_compiler/input.yul":125:126 */ 0x00 /* "object_compiler/input.yul":205:260 */ codecopy - /* "object_compiler/input.yul":275:294 */ - dup1 /* "object_compiler/input.yul":125:126 */ 0x00 /* "object_compiler/input.yul":265:295 */ diff --git a/test/cmdlineTests/optimizer_array_sload/output b/test/cmdlineTests/optimizer_array_sload/output index 448b0badc..8404525f8 100644 --- a/test/cmdlineTests/optimizer_array_sload/output +++ b/test/cmdlineTests/optimizer_array_sload/output @@ -11,11 +11,12 @@ object "Arraysum_34" { code { { /// @src 0:80:429 "contract Arraysum {..." - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("Arraysum_34_deployed") - codecopy(128, dataoffset("Arraysum_34_deployed"), _1) - return(128, _1) + let _2 := datasize("Arraysum_34_deployed") + codecopy(_1, dataoffset("Arraysum_34_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"optimizer_array_sload/input.sol" @@ -23,7 +24,7 @@ object "Arraysum_34" { code { { /// @src 0:80:429 "contract Arraysum {..." - mstore(64, 128) + mstore(64, memoryguard(0x80)) if iszero(lt(calldatasize(), 4)) { let _1 := 0 diff --git a/test/cmdlineTests/revert_strings/output b/test/cmdlineTests/revert_strings/output index 9ca27eac4..d13f9f4e5 100644 --- a/test/cmdlineTests/revert_strings/output +++ b/test/cmdlineTests/revert_strings/output @@ -11,7 +11,7 @@ IR: object "C_15" { code { /// @src 0:59:147 "contract C {..." - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_15() @@ -57,7 +57,7 @@ object "C_15" { object "C_15_deployed" { code { /// @src 0:59:147 "contract C {..." - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { diff --git a/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json b/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json index 3b25e108a..d8877a82b 100644 --- a/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json +++ b/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json @@ -1,297 +1,298 @@ {"contracts":{"C":{"C":{"evm":{"assembly":" /* \"C\":79:428 contract C... */ - mstore(0x40, 0xa0) - jumpi(tag_2, iszero(callvalue)) - 0x00 + 0xa0 dup1 - revert -tag_2: + 0x40 + mstore + jumpi(tag_5, callvalue) + 0x1f bytecodeSize codesize dup2 swap1 sub - 0xa0 - 0x1f + swap2 dup3 add not(0x1f) and - dup2 + dup4 add - swap1 + swap2 sub(shl(0x40, 0x01), 0x01) - dup3 + dup4 gt - swap1 - dup3 + dup5 + dup5 lt or - iszero tag_3 jumpi - mstore(0x00, shl(0xe0, 0x4e487b71)) - mstore(0x04, 0x41) - revert(0x00, 0x24) -tag_3: + dup1 + dup5 + swap3 + 0x20 + swap5 0x40 mstore - dup1 - dup3 - 0xa0 + dup4 codecopy - 0x20 dup2 + add + sub slt - iszero - tag_4 - jumpi - 0x00 - dup1 - revert -tag_4: - pop - pop tag_5 - mload(0xa0) + jumpi + mload /* \"C\":147:149 42 */ mstore(0x80, 0x2a) /* \"C\":203:219 stateVar = _init */ 0x00 /* \"C\":79:428 contract C... */ sstore - /* \"C\":175:223 constructor(int _init)... */ - jump - /* \"C\":79:428 contract C... */ -tag_5: mload(0x40) dataSize(sub_0) - dup1 + swap1 + dup2 dataOffset(sub_0) - dup4 + dup3 codecopy mload(0x80) - dup3 + dup2 assignImmutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") - dup1 - dup3 return +tag_5: + pop + 0x00 + dup1 + revert +tag_3: + pop + pop + pop + pop + mstore(0x00, shl(0xe0, 0x4e487b71)) + mstore(0x04, 0x41) + revert(0x00, 0x24) stop sub_0: assembly { /* \"C\":79:428 contract C... */ mstore(0x40, 0x80) - jumpi(tag_8, lt(calldatasize, 0x04)) - 0x00 - dup1 - calldataload - 0xe0 - shr - 0x26121ff0 - dup2 - eq - tag_10 - jumpi - 0x793816ec - dup2 - eq - tag_11 - jumpi - 0x9942ec6f - dup2 - eq - tag_12 - jumpi - jump(tag_9) - tag_10: - jumpi(tag_13, iszero(callvalue)) - dup2 - dup3 - revert - tag_13: - tag_14 - calldatasize - tag_1 - jump\t// in - tag_14: - /* \"C\":279:298 constVar + immutVar */ - tag_15 - /* \"C\":290:298 immutVar */ - immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") - /* \"C\":279:298 constVar + immutVar */ - tag_4 - jump\t// in - tag_15: - /* \"C\":79:428 contract C... */ - mload(0x40) - dup2 - dup2 - mstore - 0x20 - dup2 - return - tag_11: - jumpi(tag_17, iszero(callvalue)) - dup2 - dup3 - revert - tag_17: - tag_18 - calldatasize - tag_1 - jump\t// in - tag_18: - dup2 - sload - mload(0x40) - dup2 - dup2 - mstore - 0x20 - dup2 - return - tag_12: - jumpi(tag_20, iszero(callvalue)) - dup2 - dup3 - revert - tag_20: - tag_21 - calldatasize - tag_1 - jump\t// in - tag_21: - /* \"C\":375:378 int */ - tag_15 - tag_6 - jump\t// in - /* \"C\":79:428 contract C... */ - tag_9: - pop - pop - tag_8: + jumpi(tag_1, iszero(lt(calldatasize, 0x04))) 0x00 dup1 revert tag_1: 0x00 - not(0x03) - dup3 - add - slt - iszero - tag_26 + dup1 + calldataload + 0xe0 + shr + dup1 + 0x26121ff0 + eq + tag_3 jumpi + dup1 + 0x793816ec + eq + tag_5 + jumpi + 0x9942ec6f + eq + tag_7 + jumpi + pop 0x00 dup1 revert - tag_26: + tag_7: + jumpi(tag_9, callvalue) pop - jump\t// out - /* \"C\":117:119 41 */ + tag_11 + calldatasize + tag_12 + jump\t// in + tag_11: + tag_13 + /* \"C\":375:378 int */ + tag_14 + tag_15 + jump\t// in + tag_14: + /* \"C\":79:428 contract C... */ + mload(0x40) + swap1 + dup2 + mstore + swap1 + dup2 + swap1 + 0x20 + dup3 + add + swap1 + jump + tag_13: + sub + swap1 + return + tag_9: + dup1 + revert + tag_5: + pop + jumpi(tag_9, callvalue) + tag_13 + swap1 + tag_20 + calldatasize + tag_12 + jump\t// in + tag_20: + sload + mload(0x40) + swap1 + dup2 + mstore + swap1 + dup2 + swap1 + 0x20 + dup3 + add + swap1 + jump tag_3: + pop + jumpi(tag_9, callvalue) + pop + tag_23 + calldatasize + tag_12 + jump\t// in + tag_23: + tag_13 + /* \"C\":279:298 constVar + immutVar */ + tag_14 + /* \"C\":290:298 immutVar */ + immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") + /* \"C\":279:298 constVar + immutVar */ + tag_26 + jump\t// in + /* \"C\":79:428 contract C... */ + tag_12: + 0x00 + swap1 + not(0x03) + add + slt + tag_27 + jumpi + jump\t// out + tag_27: + pop + 0x00 + dup1 + revert + /* \"C\":117:119 41 */ + tag_29: + pop mstore(0x00, shl(0xe0, 0x4e487b71)) mstore(0x04, 0x11) revert(0x00, 0x24) - tag_4: - 0x00 + tag_26: sub(shl(0xff, 0x01), 0x2a) - dup3 + dup2 sgt 0x01 and - iszero - tag_31 + tag_30 jumpi - tag_31 - tag_3 - jump\t// in tag_31: - pop 0x29 add swap1 jump\t// out - tag_5: + tag_30: + tag_32 + tag_29 + jump\t// in + tag_32: + jump(tag_31) + tag_33: 0x00 - dup1 - dup3 + dup2 slt dup1 iszero sub(shl(0xff, 0x01), 0x01) - dup5 - swap1 - sub - dup6 - sgt - and - iszero - tag_34 - jumpi - tag_34 - tag_3 - jump\t// in - tag_34: - shl(0xff, 0x01) dup4 swap1 sub dup5 - slt - dup2 + sgt + and + tag_34 + jumpi + tag_35: + shl(0xff, 0x01) + dup3 + swap1 + sub + dup4 + slt and - iszero tag_36 jumpi - tag_36 - tag_3 - jump\t// in - tag_36: - pop - pop add swap1 jump\t// out + tag_36: + tag_38 + tag_29 + jump\t// in + tag_38: + add + swap1 + jump\t// out + tag_34: + tag_39 + tag_29 + jump\t// in + tag_39: + jump(tag_35) /* \"C\":304:341 modifier m()... */ - tag_6: - 0x00 + tag_15: /* \"C\":79:428 contract C... */ + 0x00 dup1 sload - /* \"C\":304:341 modifier m()... */ - dup2 + /* \"C\":117:119 41 */ + 0x01 swap1 sub(shl(0xff, 0x01), 0x01) /* \"C\":79:428 contract C... */ dup2 eq - iszero - tag_39 + tag_40 jumpi - tag_39 - tag_3 - jump\t// in - tag_39: - /* \"C\":117:119 41 */ - 0x01 + /* \"C\":304:341 modifier m()... */ + tag_41: /* \"C\":79:428 contract C... */ add - dup1 - dup3 + swap1 + dup2 + dup2 sstore /* \"C\":403:407 this */ address /* \"C\":403:411 this.f() */ extcodesize - tag_40 + iszero + tag_42 jumpi /* \"C\":79:428 contract C... */ - dup2 - dup3 - revert - /* \"C\":403:411 this.f() */ - tag_40: - /* \"C\":79:428 contract C... */ mload(0x40) shl(0xe4, 0x026121ff) /* \"C\":403:411 this.f() */ @@ -309,47 +310,95 @@ sub_0: assembly { /* \"C\":403:411 this.f() */ gas staticcall - dup1 - tag_41 - jumpi - /* \"C\":79:428 contract C... */ - mload(0x40) - returndatasize - dup6 + swap2 dup3 - returndatacopy - returndatasize - dup2 - revert - /* \"C\":403:411 this.f() */ - tag_41: - /* \"C\":79:428 contract C... */ - dup4 - /* \"C\":403:411 this.f() */ - dup2 iszero - tag_42 + tag_44 jumpi + dup1 + swap3 + tag_46 + jumpi + /* \"C\":304:341 modifier m()... */ + tag_47: + /* \"C\":392:411 stateVar + this.f() */ + pop + pop + tag_48 + swap1 + /* \"C\":392:422 stateVar + this.f() + immutVar */ + tag_49 + /* \"C\":392:411 stateVar + this.f() */ + swap3 + tag_33 + jump\t// in + tag_48: + /* \"C\":414:422 immutVar */ + immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") + /* \"C\":392:422 stateVar + this.f() + immutVar */ + swap1 + tag_33 + jump\t// in + tag_49: + /* \"C\":304:341 modifier m()... */ + swap1 + jump\t// out + /* \"C\":403:411 this.f() */ + tag_46: + /* \"C\":79:428 contract C... */ + swap1 + swap2 + pop + /* \"C\":403:411 this.f() */ returndatasize /* \"C\":79:428 contract C... */ 0x1f add not(0x1f) and - dup4 - add - 0xffffffffffffffff - dup2 - gt - dup5 dup3 + add + swap1 + 0xffffffffffffffff + dup3 + gt + dup4 + dup4 lt or - iszero - tag_43 + tag_50 jumpi + pop + swap2 + /* \"C\":403:411 this.f() */ + tag_52 + /* \"C\":392:411 stateVar + this.f() */ + tag_48 + /* \"C\":79:428 contract C... */ + swap3 + /* \"C\":392:422 stateVar + this.f() + immutVar */ + tag_49 + /* \"C\":79:428 contract C... */ + swap5 + 0x40 + mstore + /* \"C\":403:411 this.f() */ + returndatasize + dup2 + add + swap1 + tag_53 + jump\t// in + tag_52: + swap2 + dup2 + swap4 + pop + jump(tag_47) + /* \"C\":79:428 contract C... */ + tag_50: shl(0xe0, 0x4e487b71) - dup7 + dup2 mstore 0x41 /* \"C\":403:411 this.f() */ @@ -357,148 +406,143 @@ sub_0: assembly { /* \"C\":79:428 contract C... */ mstore 0x24 - dup7 - revert - tag_43: - 0x40 - mstore - /* \"C\":403:411 this.f() */ - tag_44 - returndatasize - dup5 - add - dup5 - tag_7 - jump\t// in - tag_44: - swap1 - pop - tag_42: - /* \"C\":392:411 stateVar + this.f() */ - tag_45 - dup2 - dup6 - tag_5 - jump\t// in - tag_45: swap5 pop + /* \"C\":117:119 41 */ + swap3 + pop + pop + pop + /* \"C\":79:428 contract C... */ + revert + /* \"C\":403:411 this.f() */ + tag_44: + /* \"C\":79:428 contract C... */ + swap4 pop pop pop pop - /* \"C\":392:422 stateVar + this.f() + immutVar */ - tag_46 - /* \"C\":414:422 immutVar */ - immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") - /* \"C\":392:422 stateVar + this.f() + immutVar */ + mload(0x40) + swap1 + returndatasize + swap1 dup3 - tag_5 - jump\t// in - tag_46: - /* \"C\":336:337 _ */ + returndatacopy + returndatasize + swap1 + revert + /* \"C\":403:411 this.f() */ + tag_42: + /* \"C\":79:428 contract C... */ swap2 pop pop - /* \"C\":304:341 modifier m()... */ + dup1 + revert + tag_40: + tag_54 + tag_29 + jump\t// in + tag_54: + jump(tag_41) + tag_53: swap1 - jump\t// out - /* \"C\":79:428 contract C... */ - tag_7: - 0x00 + dup2 0x20 - dup3 - dup5 + swap2 sub slt - iszero - tag_48 + tag_55 jumpi + mload + swap1 + jump\t// out + tag_55: + pop + pop 0x00 dup1 revert - tag_48: - pop - mload - swap2 - swap1 - pop - jump\t// out auxdata: } "}}},"D":{"D":{"evm":{"assembly":" /* \"D\":91:166 contract D is C(3)... */ - mstore(0x40, 0xa0) - jumpi(tag_2, iszero(callvalue)) - 0x00 + 0xa0 dup1 - revert -tag_2: + 0x40 + mstore + jumpi(tag_5, callvalue) + 0x1f bytecodeSize codesize dup2 swap1 sub - 0xa0 - 0x1f + swap2 dup3 add not(0x1f) and - dup2 + dup4 add - swap1 + swap2 sub(shl(0x40, 0x01), 0x01) - dup3 + dup4 gt - swap1 - dup3 + dup5 + dup5 lt or - iszero tag_3 jumpi - mstore(0x00, shl(0xe0, 0x4e487b71)) - mstore(0x04, 0x41) - revert(0x00, 0x24) -tag_3: + dup1 + dup5 + swap3 + 0x20 + swap5 0x40 mstore - dup1 - dup3 - 0xa0 + dup4 codecopy - 0x20 dup2 + add + sub slt - iszero - tag_4 + tag_5 jumpi + tag_7 + swap1 + mload + tag_8 + jump\t// in +tag_7: + mload(0x40) + dataSize(sub_0) + swap1 + dup2 + dataOffset(sub_0) + dup3 + codecopy + mload(0x80) + dup2 + assignImmutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") + return +tag_5: + pop 0x00 dup1 revert -tag_4: +tag_3: pop pop - tag_5 - mload(0xa0) - tag_1 - jump\t// in -tag_5: - mload(0x40) - dataSize(sub_0) - dup1 - dataOffset(sub_0) - dup4 - codecopy - mload(0x80) - dup3 - assignImmutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") - dup1 - dup3 - return + pop + pop + mstore(0x00, shl(0xe0, 0x4e487b71)) + mstore(0x04, 0x41) + revert(0x00, 0x24) /* \"D\":113:164 constructor(int _init2)... */ -tag_1: +tag_8: /* \"C\":147:149 42 */ mstore(0x80, 0x2a) /* \"D\":107:108 3 */ @@ -512,9 +556,22 @@ tag_1: sgt 0x01 and - iszero - tag_8 + tag_9 jumpi + /* \"D\":107:108 3 */ + 0x03 + /* \"D\":91:166 contract D is C(3)... */ + add + /* \"C\":203:219 stateVar = _init */ + 0x00 + /* \"D\":91:166 contract D is C(3)... */ + sstore + /* \"D\":113:164 constructor(int _init2)... */ + jump\t// out + /* \"D\":91:166 contract D is C(3)... */ +tag_9: + pop + pop shl(0xe0, 0x4e487b71) /* \"C\":203:219 stateVar = _init */ 0x00 @@ -526,234 +583,226 @@ tag_1: 0x00 /* \"D\":91:166 contract D is C(3)... */ revert -tag_8: - /* \"D\":107:108 3 */ - 0x03 - /* \"D\":91:166 contract D is C(3)... */ - add - /* \"C\":203:219 stateVar = _init */ - 0x00 - /* \"D\":91:166 contract D is C(3)... */ - sstore - /* \"D\":113:164 constructor(int _init2)... */ - jump\t// out stop sub_0: assembly { /* \"D\":91:166 contract D is C(3)... */ mstore(0x40, 0x80) - jumpi(tag_8, lt(calldatasize, 0x04)) - 0x00 - dup1 - calldataload - 0xe0 - shr - 0x26121ff0 - dup2 - eq - tag_10 - jumpi - 0x793816ec - dup2 - eq - tag_11 - jumpi - 0x9942ec6f - dup2 - eq - tag_12 - jumpi - jump(tag_9) - tag_10: - jumpi(tag_13, iszero(callvalue)) - dup2 - dup3 - revert - tag_13: - tag_14 - calldatasize - tag_1 - jump\t// in - tag_14: - /* \"C\":279:298 constVar + immutVar */ - tag_15 - /* \"C\":290:298 immutVar */ - immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") - /* \"C\":279:298 constVar + immutVar */ - tag_4 - jump\t// in - tag_15: - /* \"D\":91:166 contract D is C(3)... */ - mload(0x40) - dup2 - dup2 - mstore - 0x20 - dup2 - return - tag_11: - jumpi(tag_17, iszero(callvalue)) - dup2 - dup3 - revert - tag_17: - tag_18 - calldatasize - tag_1 - jump\t// in - tag_18: - dup2 - sload - mload(0x40) - dup2 - dup2 - mstore - 0x20 - dup2 - return - tag_12: - jumpi(tag_20, iszero(callvalue)) - dup2 - dup3 - revert - tag_20: - tag_21 - calldatasize - tag_1 - jump\t// in - tag_21: - /* \"C\":375:378 int */ - tag_15 - tag_6 - jump\t// in - /* \"D\":91:166 contract D is C(3)... */ - tag_9: - pop - pop - tag_8: + jumpi(tag_1, iszero(lt(calldatasize, 0x04))) 0x00 dup1 revert tag_1: 0x00 - not(0x03) - dup3 - add - slt - iszero - tag_26 + dup1 + calldataload + 0xe0 + shr + dup1 + 0x26121ff0 + eq + tag_3 jumpi + dup1 + 0x793816ec + eq + tag_5 + jumpi + 0x9942ec6f + eq + tag_7 + jumpi + pop 0x00 dup1 revert - tag_26: + tag_7: + jumpi(tag_9, callvalue) pop - jump\t// out - /* \"C\":117:119 41 */ + tag_11 + calldatasize + tag_12 + jump\t// in + tag_11: + tag_13 + /* \"C\":375:378 int */ + tag_14 + tag_15 + jump\t// in + tag_14: + /* \"D\":91:166 contract D is C(3)... */ + mload(0x40) + swap1 + dup2 + mstore + swap1 + dup2 + swap1 + 0x20 + dup3 + add + swap1 + jump + tag_13: + sub + swap1 + return + tag_9: + dup1 + revert + tag_5: + pop + jumpi(tag_9, callvalue) + tag_13 + swap1 + tag_20 + calldatasize + tag_12 + jump\t// in + tag_20: + sload + mload(0x40) + swap1 + dup2 + mstore + swap1 + dup2 + swap1 + 0x20 + dup3 + add + swap1 + jump tag_3: + pop + jumpi(tag_9, callvalue) + pop + tag_23 + calldatasize + tag_12 + jump\t// in + tag_23: + tag_13 + /* \"C\":279:298 constVar + immutVar */ + tag_14 + /* \"C\":290:298 immutVar */ + immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") + /* \"C\":279:298 constVar + immutVar */ + tag_26 + jump\t// in + /* \"D\":91:166 contract D is C(3)... */ + tag_12: + 0x00 + swap1 + not(0x03) + add + slt + tag_27 + jumpi + jump\t// out + tag_27: + pop + 0x00 + dup1 + revert + /* \"C\":117:119 41 */ + tag_29: + pop mstore(0x00, shl(0xe0, 0x4e487b71)) mstore(0x04, 0x11) revert(0x00, 0x24) - tag_4: - 0x00 + tag_26: sub(shl(0xff, 0x01), 0x2a) - dup3 + dup2 sgt 0x01 and - iszero - tag_31 + tag_30 jumpi - tag_31 - tag_3 - jump\t// in tag_31: - pop 0x29 add swap1 jump\t// out - tag_5: + tag_30: + tag_32 + tag_29 + jump\t// in + tag_32: + jump(tag_31) + tag_33: 0x00 - dup1 - dup3 + dup2 slt dup1 iszero sub(shl(0xff, 0x01), 0x01) - dup5 - swap1 - sub - dup6 - sgt - and - iszero - tag_34 - jumpi - tag_34 - tag_3 - jump\t// in - tag_34: - shl(0xff, 0x01) dup4 swap1 sub dup5 - slt - dup2 + sgt + and + tag_34 + jumpi + tag_35: + shl(0xff, 0x01) + dup3 + swap1 + sub + dup4 + slt and - iszero tag_36 jumpi - tag_36 - tag_3 - jump\t// in - tag_36: - pop - pop add swap1 jump\t// out + tag_36: + tag_38 + tag_29 + jump\t// in + tag_38: + add + swap1 + jump\t// out + tag_34: + tag_39 + tag_29 + jump\t// in + tag_39: + jump(tag_35) /* \"C\":304:341 modifier m()... */ - tag_6: - 0x00 + tag_15: /* \"D\":91:166 contract D is C(3)... */ + 0x00 dup1 sload - /* \"C\":304:341 modifier m()... */ - dup2 + /* \"C\":117:119 41 */ + 0x01 swap1 sub(shl(0xff, 0x01), 0x01) /* \"D\":91:166 contract D is C(3)... */ dup2 eq - iszero - tag_39 + tag_40 jumpi - tag_39 - tag_3 - jump\t// in - tag_39: - /* \"C\":117:119 41 */ - 0x01 + /* \"C\":304:341 modifier m()... */ + tag_41: /* \"D\":91:166 contract D is C(3)... */ add - dup1 - dup3 + swap1 + dup2 + dup2 sstore /* \"C\":403:407 this */ address /* \"C\":403:411 this.f() */ extcodesize - tag_40 + iszero + tag_42 jumpi /* \"D\":91:166 contract D is C(3)... */ - dup2 - dup3 - revert - /* \"C\":403:411 this.f() */ - tag_40: - /* \"D\":91:166 contract D is C(3)... */ mload(0x40) shl(0xe4, 0x026121ff) /* \"C\":403:411 this.f() */ @@ -771,47 +820,95 @@ sub_0: assembly { /* \"C\":403:411 this.f() */ gas staticcall - dup1 - tag_41 - jumpi - /* \"D\":91:166 contract D is C(3)... */ - mload(0x40) - returndatasize - dup6 + swap2 dup3 - returndatacopy - returndatasize - dup2 - revert - /* \"C\":403:411 this.f() */ - tag_41: - /* \"D\":91:166 contract D is C(3)... */ - dup4 - /* \"C\":403:411 this.f() */ - dup2 iszero - tag_42 + tag_44 jumpi + dup1 + swap3 + tag_46 + jumpi + /* \"C\":304:341 modifier m()... */ + tag_47: + /* \"C\":392:411 stateVar + this.f() */ + pop + pop + tag_48 + swap1 + /* \"C\":392:422 stateVar + this.f() + immutVar */ + tag_49 + /* \"C\":392:411 stateVar + this.f() */ + swap3 + tag_33 + jump\t// in + tag_48: + /* \"C\":414:422 immutVar */ + immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") + /* \"C\":392:422 stateVar + this.f() + immutVar */ + swap1 + tag_33 + jump\t// in + tag_49: + /* \"C\":304:341 modifier m()... */ + swap1 + jump\t// out + /* \"C\":403:411 this.f() */ + tag_46: + /* \"D\":91:166 contract D is C(3)... */ + swap1 + swap2 + pop + /* \"C\":403:411 this.f() */ returndatasize /* \"D\":91:166 contract D is C(3)... */ 0x1f add not(0x1f) and - dup4 - add - 0xffffffffffffffff - dup2 - gt - dup5 dup3 + add + swap1 + 0xffffffffffffffff + dup3 + gt + dup4 + dup4 lt or - iszero - tag_43 + tag_50 jumpi + pop + swap2 + /* \"C\":403:411 this.f() */ + tag_52 + /* \"C\":392:411 stateVar + this.f() */ + tag_48 + /* \"D\":91:166 contract D is C(3)... */ + swap3 + /* \"C\":392:422 stateVar + this.f() + immutVar */ + tag_49 + /* \"D\":91:166 contract D is C(3)... */ + swap5 + 0x40 + mstore + /* \"C\":403:411 this.f() */ + returndatasize + dup2 + add + swap1 + tag_53 + jump\t// in + tag_52: + swap2 + dup2 + swap4 + pop + jump(tag_47) + /* \"D\":91:166 contract D is C(3)... */ + tag_50: shl(0xe0, 0x4e487b71) - dup7 + dup2 mstore 0x41 /* \"C\":403:411 this.f() */ @@ -819,73 +916,64 @@ sub_0: assembly { /* \"D\":91:166 contract D is C(3)... */ mstore 0x24 - dup7 - revert - tag_43: - 0x40 - mstore - /* \"C\":403:411 this.f() */ - tag_44 - returndatasize - dup5 - add - dup5 - tag_7 - jump\t// in - tag_44: - swap1 - pop - tag_42: - /* \"C\":392:411 stateVar + this.f() */ - tag_45 - dup2 - dup6 - tag_5 - jump\t// in - tag_45: swap5 pop + /* \"C\":117:119 41 */ + swap3 + pop + pop + pop + /* \"D\":91:166 contract D is C(3)... */ + revert + /* \"C\":403:411 this.f() */ + tag_44: + /* \"D\":91:166 contract D is C(3)... */ + swap4 pop pop pop pop - /* \"C\":392:422 stateVar + this.f() + immutVar */ - tag_46 - /* \"C\":414:422 immutVar */ - immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") - /* \"C\":392:422 stateVar + this.f() + immutVar */ + mload(0x40) + swap1 + returndatasize + swap1 dup3 - tag_5 - jump\t// in - tag_46: - /* \"C\":336:337 _ */ + returndatacopy + returndatasize + swap1 + revert + /* \"C\":403:411 this.f() */ + tag_42: + /* \"D\":91:166 contract D is C(3)... */ swap2 pop pop - /* \"C\":304:341 modifier m()... */ + dup1 + revert + tag_40: + tag_54 + tag_29 + jump\t// in + tag_54: + jump(tag_41) + tag_53: swap1 - jump\t// out - /* \"D\":91:166 contract D is C(3)... */ - tag_7: - 0x00 + dup2 0x20 - dup3 - dup5 + swap2 sub slt - iszero - tag_48 + tag_55 jumpi + mload + swap1 + jump\t// out + tag_55: + pop + pop 0x00 dup1 revert - tag_48: - pop - mload - swap2 - swap1 - pop - jump\t// out auxdata: } diff --git a/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_all/output.json b/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_all/output.json index 3c630bb2d..1fa8928e1 100644 --- a/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_all/output.json +++ b/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_all/output.json @@ -72,7 +72,7 @@ sub_0: assembly { object \"C_6\" { code { /// @src 0:60:101 \"contract C {...\" - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_6() @@ -103,7 +103,7 @@ object \"C_6\" { object \"C_6_deployed\" { code { /// @src 0:60:101 \"contract C {...\" - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { @@ -187,11 +187,12 @@ object \"C_6\" { code { { /// @src 0:60:101 \"contract C {...\" - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize(\"C_6_deployed\") - codecopy(128, dataoffset(\"C_6_deployed\"), _1) - return(128, _1) + let _2 := datasize(\"C_6_deployed\") + codecopy(_1, dataoffset(\"C_6_deployed\"), _2) + return(_1, _2) } } /// @use-src 0:\"C\" @@ -199,15 +200,16 @@ object \"C_6\" { code { { /// @src 0:60:101 \"contract C {...\" - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if iszero(lt(calldatasize(), 4)) { - let _1 := 0 - if eq(0x26121ff0, shr(224, calldataload(_1))) + let _2 := 0 + if eq(0x26121ff0, shr(224, calldataload(_2))) { - if callvalue() { revert(_1, _1) } - if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) } - return(128, _1) + if callvalue() { revert(_2, _2) } + if slt(add(calldatasize(), not(3)), _2) { revert(_2, _2) } + return(_1, _2) } } revert(0, 0) diff --git a/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_location_only/output.json b/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_location_only/output.json index 1f728995d..e427b7fe1 100644 --- a/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_location_only/output.json +++ b/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_location_only/output.json @@ -72,7 +72,7 @@ sub_0: assembly { object \"C_6\" { code { /// @src 0:60:101 - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_6() @@ -103,7 +103,7 @@ object \"C_6\" { object \"C_6_deployed\" { code { /// @src 0:60:101 - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { @@ -186,11 +186,12 @@ object \"C_6\" { code { { /// @src 0:60:101 - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize(\"C_6_deployed\") - codecopy(128, dataoffset(\"C_6_deployed\"), _1) - return(128, _1) + let _2 := datasize(\"C_6_deployed\") + codecopy(_1, dataoffset(\"C_6_deployed\"), _2) + return(_1, _2) } } /// @use-src 0:\"C\" @@ -198,15 +199,16 @@ object \"C_6\" { code { { /// @src 0:60:101 - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if iszero(lt(calldatasize(), 4)) { - let _1 := 0 - if eq(0x26121ff0, shr(224, calldataload(_1))) + let _2 := 0 + if eq(0x26121ff0, shr(224, calldataload(_2))) { - if callvalue() { revert(_1, _1) } - if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) } - return(128, _1) + if callvalue() { revert(_2, _2) } + if slt(add(calldatasize(), not(3)), _2) { revert(_2, _2) } + return(_1, _2) } } revert(0, 0) diff --git a/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_none/output.json b/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_none/output.json index 8d19f60a3..e81f461d2 100644 --- a/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_none/output.json +++ b/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_none/output.json @@ -69,7 +69,7 @@ sub_0: assembly { object \"C_6\" { code { - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_6() @@ -96,7 +96,7 @@ object \"C_6\" { object \"C_6_deployed\" { code { - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { @@ -176,26 +176,28 @@ object \"C_6\" { object \"C_6\" { code { { - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize(\"C_6_deployed\") - codecopy(128, dataoffset(\"C_6_deployed\"), _1) - return(128, _1) + let _2 := datasize(\"C_6_deployed\") + codecopy(_1, dataoffset(\"C_6_deployed\"), _2) + return(_1, _2) } } /// @use-src 0:\"C\" object \"C_6_deployed\" { code { { - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if iszero(lt(calldatasize(), 4)) { - let _1 := 0 - if eq(0x26121ff0, shr(224, calldataload(_1))) + let _2 := 0 + if eq(0x26121ff0, shr(224, calldataload(_2))) { - if callvalue() { revert(_1, _1) } - if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) } - return(128, _1) + if callvalue() { revert(_2, _2) } + if slt(add(calldatasize(), not(3)), _2) { revert(_2, _2) } + return(_1, _2) } } revert(0, 0) diff --git a/test/cmdlineTests/standard_debug_info_in_yul_location/output.json b/test/cmdlineTests/standard_debug_info_in_yul_location/output.json index 7a77d60f4..6a105aadd 100644 --- a/test/cmdlineTests/standard_debug_info_in_yul_location/output.json +++ b/test/cmdlineTests/standard_debug_info_in_yul_location/output.json @@ -10,7 +10,7 @@ object \"C_54\" { code { /// @src 0:79:435 \"contract C...\" - mstore(64, 160) + mstore(64, memoryguard(160)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } let _1 := copy_arguments_for_constructor_20_object_C_54() @@ -161,7 +161,7 @@ object \"C_54\" { object \"C_54_deployed\" { code { /// @src 0:79:435 \"contract C...\" - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { @@ -592,30 +592,31 @@ object \"C_54\" { code { { /// @src 0:79:435 \"contract C...\" - mstore(64, 160) + let _1 := memoryguard(0xa0) + mstore(64, _1) if callvalue() { revert(0, 0) } let programSize := datasize(\"C_54\") let argSize := sub(codesize(), programSize) - let newFreePtr := add(160, and(add(argSize, 31), not(31))) - if or(gt(newFreePtr, sub(shl(64, 1), 1)), lt(newFreePtr, 160)) + let newFreePtr := add(_1, and(add(argSize, 31), not(31))) + if or(gt(newFreePtr, sub(shl(64, 1), 1)), lt(newFreePtr, _1)) { mstore(/** @src -1:-1:-1 */ 0, /** @src 0:79:435 \"contract C...\" */ shl(224, 0x4e487b71)) mstore(4, 0x41) revert(/** @src -1:-1:-1 */ 0, /** @src 0:79:435 \"contract C...\" */ 0x24) } mstore(64, newFreePtr) - codecopy(160, programSize, argSize) - if slt(argSize, 32) + codecopy(_1, programSize, argSize) + if slt(sub(add(_1, argSize), _1), 32) { revert(/** @src -1:-1:-1 */ 0, 0) } /// @src 0:79:435 \"contract C...\" - constructor_C(mload(160)) - let _1 := mload(64) - let _2 := datasize(\"C_54_deployed\") - codecopy(_1, dataoffset(\"C_54_deployed\"), _2) - setimmutable(_1, \"8\", mload(128)) - return(_1, _2) + constructor_C(mload(_1)) + let _2 := mload(64) + let _3 := datasize(\"C_54_deployed\") + codecopy(_2, dataoffset(\"C_54_deployed\"), _3) + setimmutable(_2, \"8\", mload(128)) + return(_2, _3) } /// @ast-id 20 @src 0:182:230 \"constructor(int _init)...\" function constructor_C(var_init) @@ -631,7 +632,7 @@ object \"C_54\" { code { { /// @src 0:79:435 \"contract C...\" - mstore(64, 128) + mstore(64, memoryguard(0x80)) if iszero(lt(calldatasize(), 4)) { let _1 := 0 @@ -774,7 +775,7 @@ object \"C_54\" { object \"D_72\" { code { /// @src 1:91:166 \"contract D is C(3)...\" - mstore(64, 160) + mstore(64, memoryguard(160)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } let _1 := copy_arguments_for_constructor_71_object_D_72() @@ -993,7 +994,7 @@ object \"D_72\" { object \"D_72_deployed\" { code { /// @src 1:91:166 \"contract D is C(3)...\" - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { @@ -1424,30 +1425,31 @@ object \"D_72\" { code { { /// @src 1:91:166 \"contract D is C(3)...\" - mstore(64, 160) + let _1 := memoryguard(0xa0) + mstore(64, _1) if callvalue() { revert(0, 0) } let programSize := datasize(\"D_72\") let argSize := sub(codesize(), programSize) - let newFreePtr := add(160, and(add(argSize, 31), not(31))) - if or(gt(newFreePtr, sub(shl(64, 1), 1)), lt(newFreePtr, 160)) + let newFreePtr := add(_1, and(add(argSize, 31), not(31))) + if or(gt(newFreePtr, sub(shl(64, 1), 1)), lt(newFreePtr, _1)) { mstore(/** @src -1:-1:-1 */ 0, /** @src 1:91:166 \"contract D is C(3)...\" */ shl(224, 0x4e487b71)) mstore(4, 0x41) revert(/** @src -1:-1:-1 */ 0, /** @src 1:91:166 \"contract D is C(3)...\" */ 0x24) } mstore(64, newFreePtr) - codecopy(160, programSize, argSize) - if slt(argSize, 32) + codecopy(_1, programSize, argSize) + if slt(sub(add(_1, argSize), _1), 32) { revert(/** @src -1:-1:-1 */ 0, 0) } /// @src 1:91:166 \"contract D is C(3)...\" - constructor_D(mload(160)) - let _1 := mload(64) - let _2 := datasize(\"D_72_deployed\") - codecopy(_1, dataoffset(\"D_72_deployed\"), _2) - setimmutable(_1, \"8\", mload(128)) - return(_1, _2) + constructor_D(mload(_1)) + let _2 := mload(64) + let _3 := datasize(\"D_72_deployed\") + codecopy(_2, dataoffset(\"D_72_deployed\"), _3) + setimmutable(_2, \"8\", mload(128)) + return(_2, _3) } /// @ast-id 71 @src 1:113:164 \"constructor(int _init2)...\" function constructor_D(var_init2) @@ -1471,7 +1473,7 @@ object \"D_72\" { code { { /// @src 1:91:166 \"contract D is C(3)...\" - mstore(64, 128) + mstore(64, memoryguard(0x80)) if iszero(lt(calldatasize(), 4)) { let _1 := 0 diff --git a/test/cmdlineTests/standard_ewasm_requested/output.json b/test/cmdlineTests/standard_ewasm_requested/output.json index c70693bc6..a8ab1fd0b 100644 --- a/test/cmdlineTests/standard_ewasm_requested/output.json +++ b/test/cmdlineTests/standard_ewasm_requested/output.json @@ -17,7 +17,7 @@ (local $z3 i64) (local $_1 i64) (block $label_ - (local.set $p (call $u256_to_i32_726)) + (local.set $p (call $u256_to_i32_716)) (local.set $r (i32.add (local.get $p) (i32.const 64))) (if (i32.lt_u (local.get $r) (local.get $p)) (then (unreachable))) @@ -30,14 +30,14 @@ (call $eth.getCallValue (i32.const 0)) (local.set $z3 (i64.load (i32.const 8))) (if (i32.eqz (i64.eqz (i64.or (i64.or (i64.const 0) (i64.const 0)) (i64.or (local.get $z3) (i64.load (i32.const 0)))))) (then - (call $eth.revert (call $to_internal_i32ptr) (call $u256_to_i32_344)))) + (call $eth.revert (call $to_internal_i32ptr_334) (call $u256_to_i32_333)))) (local.set $_1 (datasize \"C_3_deployed\")) - (call $eth.codeCopy (call $to_internal_i32ptr_348) (call $u256_to_i32 (dataoffset \"C_3_deployed\")) (call $u256_to_i32 (local.get $_1))) - (call $eth.finish (call $to_internal_i32ptr_348) (call $u256_to_i32 (local.get $_1))) + (call $eth.codeCopy (call $to_internal_i32ptr) (call $u256_to_i32 (dataoffset \"C_3_deployed\")) (call $u256_to_i32 (local.get $_1))) + (call $eth.finish (call $to_internal_i32ptr) (call $u256_to_i32 (local.get $_1))) ) ) -(func $u256_to_i32_344 +(func $u256_to_i32_333 (result i32) (local $v i32) (local $_1 i64) @@ -68,7 +68,7 @@ (local.get $v) ) -(func $u256_to_i32_726 +(func $u256_to_i32_716 (result i32) (local $v i32) (block $label__3 @@ -82,12 +82,12 @@ (local.get $v) ) -(func $to_internal_i32ptr +(func $to_internal_i32ptr_334 (result i32) (local $r i32) (local $p i32) (block $label__4 - (local.set $p (call $u256_to_i32_344)) + (local.set $p (call $u256_to_i32_333)) (local.set $r (i32.add (local.get $p) (i32.const 64))) (if (i32.lt_u (local.get $r) (local.get $p)) (then (unreachable))) @@ -96,7 +96,7 @@ (local.get $r) ) -(func $to_internal_i32ptr_348 +(func $to_internal_i32ptr (result i32) (local $r i32) (local $v i32) diff --git a/test/cmdlineTests/standard_irOptimized_requested/output.json b/test/cmdlineTests/standard_irOptimized_requested/output.json index 78499140c..c56849339 100644 --- a/test/cmdlineTests/standard_irOptimized_requested/output.json +++ b/test/cmdlineTests/standard_irOptimized_requested/output.json @@ -9,7 +9,7 @@ object \"C_7\" { code { /// @src 0:79:121 \"contract C { function f() public pure {} }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() @@ -29,7 +29,7 @@ object \"C_7\" { object \"C_7_deployed\" { code { /// @src 0:79:121 \"contract C { function f() public pure {} }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { let selector := shift_right_224_unsigned(calldataload(0)) diff --git a/test/cmdlineTests/standard_ir_requested/output.json b/test/cmdlineTests/standard_ir_requested/output.json index 2da612abc..59f07f768 100644 --- a/test/cmdlineTests/standard_ir_requested/output.json +++ b/test/cmdlineTests/standard_ir_requested/output.json @@ -10,7 +10,7 @@ object \"C_7\" { code { /// @src 0:79:121 \"contract C { function f() public pure {} }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_7() @@ -41,7 +41,7 @@ object \"C_7\" { object \"C_7_deployed\" { code { /// @src 0:79:121 \"contract C { function f() public pure {} }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { diff --git a/test/cmdlineTests/standard_viair_requested/output.json b/test/cmdlineTests/standard_viair_requested/output.json index 4bf34fd7a..b72923f48 100644 --- a/test/cmdlineTests/standard_viair_requested/output.json +++ b/test/cmdlineTests/standard_viair_requested/output.json @@ -10,7 +10,7 @@ object \"C_3\" { code { /// @src 0:79:92 \"contract C {}\" - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_3() @@ -41,7 +41,7 @@ object \"C_3\" { object \"C_3_deployed\" { code { /// @src 0:79:92 \"contract C {}\" - mstore(64, 128) + mstore(64, memoryguard(128)) revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() @@ -79,7 +79,7 @@ object \"C_3\" { object \"D_16\" { code { /// @src 0:93:146 \"contract D { function f() public { C c = new C(); } }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_D_16() @@ -110,7 +110,7 @@ object \"D_16\" { object \"D_16_deployed\" { code { /// @src 0:93:146 \"contract D { function f() public { C c = new C(); } }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { @@ -212,7 +212,7 @@ object \"D_16\" { object \"C_3\" { code { /// @src 0:79:92 \"contract C {}\" - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_3() @@ -243,7 +243,7 @@ object \"D_16\" { object \"C_3_deployed\" { code { /// @src 0:79:92 \"contract C {}\" - mstore(64, 128) + mstore(64, memoryguard(128)) revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() diff --git a/test/cmdlineTests/standard_yul_optimiserSteps/output.json b/test/cmdlineTests/standard_yul_optimiserSteps/output.json index 3caeed8db..4071589cb 100644 --- a/test/cmdlineTests/standard_yul_optimiserSteps/output.json +++ b/test/cmdlineTests/standard_yul_optimiserSteps/output.json @@ -1,10 +1,12 @@ -{"contracts":{"A":{"object":{"evm":{"assembly":" /* \"A\":17:18 */ +{"contracts":{"A":{"object":{"evm":{"assembly":" /* \"A\":38:39 */ 0x00 /* \"A\":11:19 */ dup1 mload /* \"A\":20:40 */ sstore + /* \"A\":0:42 */ + stop ","bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""}},"ir":"object \"object\" { code { let x := mload(0) diff --git a/test/cmdlineTests/standard_yul_optimized/output.json b/test/cmdlineTests/standard_yul_optimized/output.json index a5217c672..371a0816b 100644 --- a/test/cmdlineTests/standard_yul_optimized/output.json +++ b/test/cmdlineTests/standard_yul_optimized/output.json @@ -1,10 +1,12 @@ {"contracts":{"A":{"object":{"evm":{"assembly":" /* \"A\":17:18 */ 0x00 - dup1 /* \"A\":11:19 */ + dup1 mload /* \"A\":20:40 */ sstore + /* \"A\":0:42 */ + stop ","bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""}},"ir":"object \"object\" { code { let x := mload(0) diff --git a/test/cmdlineTests/standard_yul_stack_opt/output.json b/test/cmdlineTests/standard_yul_stack_opt/output.json index 0fd77310e..f041adaa8 100644 --- a/test/cmdlineTests/standard_yul_stack_opt/output.json +++ b/test/cmdlineTests/standard_yul_stack_opt/output.json @@ -1,17 +1,15 @@ {"contracts":{"A":{"object":{"evm":{"assembly":" /* \"A\":16:17 */ 0x01 - dup1 /* \"A\":27:28 */ 0x00 /* \"A\":20:32 */ sstore - pop /* \"A\":50:51 */ 0x02 - dup1 /* \"A\":61:63 */ 0x20 /* \"A\":54:67 */ sstore - pop + /* \"A\":0:72 */ + stop "}}}},"errors":[{"component":"general","formattedMessage":"Yul is still experimental. Please use the output with care.","message":"Yul is still experimental. Please use the output with care.","severity":"warning","type":"Warning"}]} diff --git a/test/cmdlineTests/strict_asm_optimizer_steps/output b/test/cmdlineTests/strict_asm_optimizer_steps/output index bf9f34e7a..0f7a59b97 100644 --- a/test/cmdlineTests/strict_asm_optimizer_steps/output +++ b/test/cmdlineTests/strict_asm_optimizer_steps/output @@ -25,7 +25,7 @@ object "C_6" { Binary representation: -60806040523415600e57600080fd5b600e601c600039600e6000f3fe60806040523615600055600080fd +608060405234601557600e601b600039600e6000f35b600080fdfe60806040523615600055600080fd Text representation: /* "strict_asm_optimizer_steps/input.yul":45:48 */ @@ -37,17 +37,8 @@ Text representation: /* "strict_asm_optimizer_steps/input.yul":61:72 */ callvalue /* "strict_asm_optimizer_steps/input.yul":58:89 */ - iszero tag_1 jumpi - /* "strict_asm_optimizer_steps/input.yul":85:86 */ - 0x00 - /* "strict_asm_optimizer_steps/input.yul":82:83 */ - dup1 - /* "strict_asm_optimizer_steps/input.yul":75:87 */ - revert - /* "strict_asm_optimizer_steps/input.yul":58:89 */ -tag_1: /* "strict_asm_optimizer_steps/input.yul":138:162 */ dataSize(sub_0) /* "strict_asm_optimizer_steps/input.yul":110:136 */ @@ -62,6 +53,13 @@ tag_1: 0x00 /* "strict_asm_optimizer_steps/input.yul":172:207 */ return + /* "strict_asm_optimizer_steps/input.yul":73:89 */ +tag_1: + /* "strict_asm_optimizer_steps/input.yul":85:86 */ + 0x00 + /* "strict_asm_optimizer_steps/input.yul":75:87 */ + dup1 + revert stop sub_0: assembly { @@ -81,8 +79,7 @@ sub_0: assembly { sstore /* "strict_asm_optimizer_steps/input.yul":576:577 */ 0x00 - /* "strict_asm_optimizer_steps/input.yul":573:574 */ - dup1 /* "strict_asm_optimizer_steps/input.yul":566:578 */ + dup1 revert } diff --git a/test/cmdlineTests/viair_abicoder_v1/output b/test/cmdlineTests/viair_abicoder_v1/output index a23730702..cedda56dc 100644 --- a/test/cmdlineTests/viair_abicoder_v1/output +++ b/test/cmdlineTests/viair_abicoder_v1/output @@ -11,7 +11,7 @@ IR: object "test_11" { code { /// @src 0:79:169 "contract test {..." - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_test_11() @@ -42,7 +42,7 @@ object "test_11" { object "test_11_deployed" { code { /// @src 0:79:169 "contract test {..." - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { diff --git a/test/cmdlineTests/viair_subobjects/output b/test/cmdlineTests/viair_subobjects/output index eef7d27e8..4b388665c 100644 --- a/test/cmdlineTests/viair_subobjects/output +++ b/test/cmdlineTests/viair_subobjects/output @@ -17,11 +17,12 @@ object "C_3" { code { { /// @src 0:82:95 "contract C {}" - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("C_3_deployed") - codecopy(128, dataoffset("C_3_deployed"), _1) - return(128, _1) + let _2 := datasize("C_3_deployed") + codecopy(_1, dataoffset("C_3_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"viair_subobjects/input.sol" @@ -29,7 +30,7 @@ object "C_3" { code { { /// @src 0:82:95 "contract C {}" - mstore(64, 128) + mstore(64, memoryguard(0x80)) revert(0, 0) } } @@ -56,11 +57,12 @@ object "D_16" { code { { /// @src 0:96:165 "contract D {..." - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("D_16_deployed") - codecopy(128, dataoffset("D_16_deployed"), _1) - return(128, _1) + let _2 := datasize("D_16_deployed") + codecopy(_1, dataoffset("D_16_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"viair_subobjects/input.sol" @@ -68,35 +70,35 @@ object "D_16" { code { { /// @src 0:96:165 "contract D {..." - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if iszero(lt(calldatasize(), 4)) { - let _1 := 0 - if eq(0x26121ff0, shr(224, calldataload(_1))) + let _2 := 0 + if eq(0x26121ff0, shr(224, calldataload(_2))) { - if callvalue() { revert(_1, _1) } - if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) } - /// @src 0:149:156 "new C()" - let _2 := datasize("C_3") - let _3 := add(/** @src 0:96:165 "contract D {..." */ 128, /** @src 0:149:156 "new C()" */ _2) - if or(gt(_3, 0xffffffffffffffff), lt(_3, /** @src 0:96:165 "contract D {..." */ 128)) + if callvalue() { revert(_2, _2) } + if slt(add(calldatasize(), not(3)), _2) { revert(_2, _2) } /// @src 0:149:156 "new C()" + let _3 := datasize("C_3") + let _4 := add(_1, _3) + if or(gt(_4, 0xffffffffffffffff), lt(_4, _1)) { /// @src 0:96:165 "contract D {..." - mstore(_1, shl(224, 0x4e487b71)) + mstore(_2, shl(224, 0x4e487b71)) mstore(4, 0x41) - revert(_1, 0x24) + revert(_2, 0x24) } /// @src 0:149:156 "new C()" - datacopy(/** @src 0:96:165 "contract D {..." */ 128, /** @src 0:149:156 "new C()" */ dataoffset("C_3"), _2) - if iszero(create(/** @src 0:96:165 "contract D {..." */ _1, 128, /** @src 0:149:156 "new C()" */ _2)) + datacopy(_1, dataoffset("C_3"), _3) + if iszero(create(/** @src 0:96:165 "contract D {..." */ _2, /** @src 0:149:156 "new C()" */ _1, sub(_4, _1))) { /// @src 0:96:165 "contract D {..." let pos := mload(64) - returndatacopy(pos, _1, returndatasize()) + returndatacopy(pos, _2, returndatasize()) revert(pos, returndatasize()) } - return(mload(64), _1) + return(mload(64), _2) } } revert(0, 0) @@ -107,11 +109,12 @@ object "D_16" { code { { /// @src 0:82:95 "contract C {}" - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("C_3_deployed") - codecopy(128, dataoffset("C_3_deployed"), _1) - return(128, _1) + let _2 := datasize("C_3_deployed") + codecopy(_1, dataoffset("C_3_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"viair_subobjects/input.sol" @@ -119,7 +122,7 @@ object "D_16" { code { { /// @src 0:82:95 "contract C {}" - mstore(64, 128) + mstore(64, memoryguard(0x80)) revert(0, 0) } } diff --git a/test/cmdlineTests/yul_optimize_runs/output b/test/cmdlineTests/yul_optimize_runs/output index 4c98ec30e..b95184440 100644 --- a/test/cmdlineTests/yul_optimize_runs/output +++ b/test/cmdlineTests/yul_optimize_runs/output @@ -21,20 +21,18 @@ object "RunsTest1" { Binary representation: -602480600d600039806000f3fe7fabc1234500000000000000000000000000000000000000000000000000000000600055 +602580600c6000396000f3fe7fabc123450000000000000000000000000000000000000000000000000000000060005500 Text representation: /* "yul_optimize_runs/input.yul":106:125 */ dataSize(sub_0) - dup1 /* "yul_optimize_runs/input.yul":83:104 */ + dup1 dataOffset(sub_0) /* "yul_optimize_runs/input.yul":80:81 */ 0x00 /* "yul_optimize_runs/input.yul":71:126 */ codecopy - /* "yul_optimize_runs/input.yul":145:164 */ - dup1 /* "yul_optimize_runs/input.yul":80:81 */ 0x00 /* "yul_optimize_runs/input.yul":135:165 */ @@ -48,4 +46,6 @@ sub_0: assembly { 0x00 /* "yul_optimize_runs/input.yul":270:288 */ sstore + /* "yul_optimize_runs/input.yul":208:298 */ + stop } diff --git a/test/cmdlineTests/yul_optimizer_steps/output b/test/cmdlineTests/yul_optimizer_steps/output index 8e4cc7e88..a88ce164a 100644 --- a/test/cmdlineTests/yul_optimizer_steps/output +++ b/test/cmdlineTests/yul_optimizer_steps/output @@ -11,7 +11,7 @@ object "C_7" { code { { /// @src 0:80:112 "contract C..." - mstore(64, 128) + mstore(64, memoryguard(0x80)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() @@ -30,7 +30,7 @@ object "C_7" { code { { /// @src 0:80:112 "contract C..." - mstore(64, 128) + mstore(64, memoryguard(0x80)) revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() } function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() diff --git a/test/cmdlineTests/yul_optimizer_steps_nested_brackets/output b/test/cmdlineTests/yul_optimizer_steps_nested_brackets/output index 63f08a35d..cc67ca5bc 100644 --- a/test/cmdlineTests/yul_optimizer_steps_nested_brackets/output +++ b/test/cmdlineTests/yul_optimizer_steps_nested_brackets/output @@ -11,7 +11,7 @@ object "C_6" { code { { /// @src 0:60:103 "contract C..." - mstore(64, 128) + mstore(64, memoryguard(0x80)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() @@ -121,7 +121,7 @@ object "C_6" { code { { /// @src 0:60:103 "contract C..." - mstore(64, 128) + mstore(64, memoryguard(0x80)) if iszero(lt(calldatasize(), 4)) { let selector := shift_right_unsigned(calldataload(0)) diff --git a/test/cmdlineTests/yul_string_format_ascii/output.json b/test/cmdlineTests/yul_string_format_ascii/output.json index ae7a926fe..2354929e4 100644 --- a/test/cmdlineTests/yul_string_format_ascii/output.json +++ b/test/cmdlineTests/yul_string_format_ascii/output.json @@ -10,7 +10,7 @@ object \"C_11\" { code { /// @src 0:78:164 \"contract C { function f() external pure returns (string memory) { return \\\"abcabc\\\"; } }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_11() @@ -41,7 +41,7 @@ object \"C_11\" { object \"C_11_deployed\" { code { /// @src 0:78:164 \"contract C { function f() external pure returns (string memory) { return \\\"abcabc\\\"; } }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { diff --git a/test/cmdlineTests/yul_string_format_ascii_bytes32/output.json b/test/cmdlineTests/yul_string_format_ascii_bytes32/output.json index 59a93a7bf..84e9ff271 100644 --- a/test/cmdlineTests/yul_string_format_ascii_bytes32/output.json +++ b/test/cmdlineTests/yul_string_format_ascii_bytes32/output.json @@ -10,7 +10,7 @@ object \"C_11\" { code { /// @src 0:78:158 \"contract C { function f() external pure returns (bytes32) { return \\\"abcabc\\\"; } }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_11() @@ -41,7 +41,7 @@ object \"C_11\" { object \"C_11_deployed\" { code { /// @src 0:78:158 \"contract C { function f() external pure returns (bytes32) { return \\\"abcabc\\\"; } }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { diff --git a/test/cmdlineTests/yul_string_format_ascii_bytes32_from_number/output.json b/test/cmdlineTests/yul_string_format_ascii_bytes32_from_number/output.json index 79d35a338..716a1cc6e 100644 --- a/test/cmdlineTests/yul_string_format_ascii_bytes32_from_number/output.json +++ b/test/cmdlineTests/yul_string_format_ascii_bytes32_from_number/output.json @@ -10,7 +10,7 @@ object \"C_11\" { code { /// @src 0:78:159 \"contract C { function f() external pure returns (bytes4) { return 0x61626364; } }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_11() @@ -41,7 +41,7 @@ object \"C_11\" { object \"C_11_deployed\" { code { /// @src 0:78:159 \"contract C { function f() external pure returns (bytes4) { return 0x61626364; } }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { diff --git a/test/cmdlineTests/yul_string_format_ascii_long/output.json b/test/cmdlineTests/yul_string_format_ascii_long/output.json index 932a5c28c..1f52e103b 100644 --- a/test/cmdlineTests/yul_string_format_ascii_long/output.json +++ b/test/cmdlineTests/yul_string_format_ascii_long/output.json @@ -10,7 +10,7 @@ object \"C_11\" { code { /// @src 0:78:243 \"contract C { function f() external pure returns (string memory) { return \\\"abcdabcdcafecafeabcdabcdcafecafeffffzzzzoooo0123456789,.<,>.?:;'[{]}|`~!@#$%^&*()-_=+\\\"; } }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_11() @@ -41,7 +41,7 @@ object \"C_11\" { object \"C_11_deployed\" { code { /// @src 0:78:243 \"contract C { function f() external pure returns (string memory) { return \\\"abcdabcdcafecafeabcdabcdcafecafeffffzzzzoooo0123456789,.<,>.?:;'[{]}|`~!@#$%^&*()-_=+\\\"; } }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { diff --git a/test/cmdlineTests/yul_string_format_hex/output.json b/test/cmdlineTests/yul_string_format_hex/output.json index da8f873a3..04166a760 100644 --- a/test/cmdlineTests/yul_string_format_hex/output.json +++ b/test/cmdlineTests/yul_string_format_hex/output.json @@ -10,7 +10,7 @@ object \"C_11\" { code { /// @src 0:78:159 \"contract C { function f() external pure returns (bytes4) { return 0xaabbccdd; } }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_11() @@ -41,7 +41,7 @@ object \"C_11\" { object \"C_11_deployed\" { code { /// @src 0:78:159 \"contract C { function f() external pure returns (bytes4) { return 0xaabbccdd; } }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { diff --git a/test/cmdlineTests/yul_verbatim_msize/output b/test/cmdlineTests/yul_verbatim_msize/output index 5f67aa85e..991fcbdb0 100644 --- a/test/cmdlineTests/yul_verbatim_msize/output +++ b/test/cmdlineTests/yul_verbatim_msize/output @@ -14,7 +14,7 @@ object "object" { Binary representation: -612000515061616002600055 +61200051506161600260005500 Text representation: /* "yul_verbatim_msize/input.yul":125:131 */ @@ -30,3 +30,5 @@ Text representation: 0x00 /* "yul_verbatim_msize/input.yul":162:174 */ sstore + /* "yul_verbatim_msize/input.yul":0:176 */ + stop diff --git a/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_v2_storage.sol b/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_v2_storage.sol index 4161cb7d8..06f9bcbbf 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_v2_storage.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_v2_storage.sol @@ -24,6 +24,6 @@ contract C { // compileViaYul: also // ---- // f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb -// gas irOptimized: 203522 +// gas irOptimized: 203312 // gas legacy: 206084 // gas legacyOptimized: 203068 diff --git a/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol b/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol index 61b8f3810..ddd536a38 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol @@ -60,10 +60,10 @@ contract C { // compileViaYul: also // ---- // test_bytes() -> -// gas irOptimized: 394829 +// gas irOptimized: 377545 // gas legacy: 423563 // gas legacyOptimized: 331391 // test_uint256() -> -// gas irOptimized: 553331 +// gas irOptimized: 528726 // gas legacy: 591392 // gas legacyOptimized: 456137 diff --git a/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol b/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol index 458c11893..8fe170e91 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol @@ -26,6 +26,6 @@ contract C { // ---- // library: L // f() -> 8, 7, 1, 2, 7, 12 -// gas irOptimized: 167615 +// gas irOptimized: 167580 // gas legacy: 169475 // gas legacyOptimized: 167397 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol index 7b7854c23..3a4a23fef 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol @@ -61,10 +61,10 @@ contract C { // compileViaYul: also // ---- // test_bytes() -> -// gas irOptimized: 394829 +// gas irOptimized: 377545 // gas legacy: 423563 // gas legacyOptimized: 331391 // test_uint256() -> -// gas irOptimized: 553331 +// gas irOptimized: 528726 // gas legacy: 591392 // gas legacyOptimized: 456137 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2.sol index d475ffa19..3e9697698 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2.sol @@ -53,6 +53,6 @@ contract C { // f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, "abc" // f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, "abc" // f4() -> 0x20, 0x160, 0x1, 0x80, 0xc0, 0x2, 0x3, "abc", 0x7, 0x40, 0x2, 0x2, 0x3 -// gas irOptimized: 113296 +// gas irOptimized: 113361 // gas legacy: 114900 // gas legacyOptimized: 112606 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol index bf57dbe6f..b730f3588 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol @@ -32,6 +32,6 @@ contract C is B { // compileViaYul: also // ---- // test() -> 77 -// gas irOptimized: 121699 +// gas irOptimized: 120044 // gas legacy: 155221 // gas legacyOptimized: 111678 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol index 7fceb5935..7832ef601 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol @@ -40,5 +40,5 @@ contract C is B { // compileViaYul: also // ---- // test() -> 5, 10 -// gas irOptimized: 88225 +// gas irOptimized: 87578 // gas legacy: 99137 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol b/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol index 2841ef243..bf42f8776 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol @@ -21,6 +21,6 @@ contract C { // f(uint256[][1]): 32, 32, 0 -> true // f(uint256[][1]): 32, 32, 1, 42 -> true // f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true -// gas irOptimized: 177581 +// gas irOptimized: 172204 // gas legacy: 141900 // gas legacyOptimized: 121788 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/storage_array_encoding.sol b/test/libsolidity/semanticTests/abiEncoderV2/storage_array_encoding.sol index 12f12ef29..1f836bfaf 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/storage_array_encoding.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/storage_array_encoding.sol @@ -19,10 +19,10 @@ contract C { // compileViaYul: also // ---- // h(uint256[2][]): 0x20, 3, 123, 124, 223, 224, 323, 324 -> 32, 256, 0x20, 3, 123, 124, 223, 224, 323, 324 -// gas irOptimized: 181123 +// gas irOptimized: 180925 // gas legacy: 184929 // gas legacyOptimized: 181504 // i(uint256[2][2]): 123, 124, 223, 224 -> 32, 128, 123, 124, 223, 224 -// gas irOptimized: 112627 +// gas irOptimized: 112535 // gas legacy: 115468 // gas legacyOptimized: 112988 diff --git a/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol b/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol index cbdaa381f..b6c6ad5f0 100644 --- a/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol +++ b/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol @@ -11,6 +11,6 @@ contract C { // compileViaYul: also // ---- // f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, "abcdefg" -> 0x21, 0x40, 0x7, "abcdefg" -// gas irOptimized: 135996 +// gas irOptimized: 135918 // gas legacy: 137190 // gas legacyOptimized: 136082 diff --git a/test/libsolidity/semanticTests/array/arrays_complex_from_and_to_storage.sol b/test/libsolidity/semanticTests/array/arrays_complex_from_and_to_storage.sol index 596e76a66..e8d567059 100644 --- a/test/libsolidity/semanticTests/array/arrays_complex_from_and_to_storage.sol +++ b/test/libsolidity/semanticTests/array/arrays_complex_from_and_to_storage.sol @@ -14,7 +14,7 @@ contract Test { // compileViaYul: also // ---- // set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06 -// gas irOptimized: 189239 +// gas irOptimized: 189910 // gas legacy: 211149 // gas legacyOptimized: 206054 // data(uint256,uint256): 0x02, 0x02 -> 0x09 diff --git a/test/libsolidity/semanticTests/array/byte_array_storage_layout.sol b/test/libsolidity/semanticTests/array/byte_array_storage_layout.sol index 251489660..2c238a54b 100644 --- a/test/libsolidity/semanticTests/array/byte_array_storage_layout.sol +++ b/test/libsolidity/semanticTests/array/byte_array_storage_layout.sol @@ -47,7 +47,7 @@ contract c { // gas legacyOptimized: 58606 // storageEmpty -> 0 // test_long() -> 67 -// gas irOptimized: 90759 +// gas irOptimized: 89148 // gas legacy: 103590 // gas legacyOptimized: 101044 // storageEmpty -> 0 diff --git a/test/libsolidity/semanticTests/array/byte_array_transitional_2.sol b/test/libsolidity/semanticTests/array/byte_array_transitional_2.sol index a4403c3d7..31879057a 100644 --- a/test/libsolidity/semanticTests/array/byte_array_transitional_2.sol +++ b/test/libsolidity/semanticTests/array/byte_array_transitional_2.sol @@ -19,6 +19,6 @@ contract c { // compileViaYul: also // ---- // test() -> 0 -// gas irOptimized: 165224 +// gas irOptimized: 158143 // gas legacy: 189715 // gas legacyOptimized: 184472 diff --git a/test/libsolidity/semanticTests/array/bytes_length_member.sol b/test/libsolidity/semanticTests/array/bytes_length_member.sol index aaf990ef6..bb4e21e16 100644 --- a/test/libsolidity/semanticTests/array/bytes_length_member.sol +++ b/test/libsolidity/semanticTests/array/bytes_length_member.sol @@ -15,7 +15,7 @@ contract c { // ---- // getLength() -> 0 // set(): 1, 2 -> true -// gas irOptimized: 110439 +// gas irOptimized: 110433 // gas legacy: 110726 // gas legacyOptimized: 110567 // getLength() -> 68 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_calldata_storage.sol b/test/libsolidity/semanticTests/array/copying/array_copy_calldata_storage.sol index 4795624b4..2a401cd87 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_calldata_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_calldata_storage.sol @@ -22,7 +22,7 @@ contract c { // compileViaYul: also // ---- // store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32 -// gas irOptimized: 650971 +// gas irOptimized: 650669 // gas legacy: 694515 // gas legacyOptimized: 694013 // retrieve() -> 9, 28, 9, 28, 4, 3, 32 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint128.sol b/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint128.sol index 91ae6913f..3449cdc2d 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint128.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint128.sol @@ -23,6 +23,6 @@ contract C { // compileViaYul: also // ---- // f() -> true -// gas irOptimized: 92843 +// gas irOptimized: 92740 // gas legacy: 93035 // gas legacyOptimized: 92257 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint40.sol b/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint40.sol index 2b74d52e4..73abd2cf7 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint40.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint40.sol @@ -48,6 +48,6 @@ contract C { // compileViaYul: also // ---- // f() -> true -// gas irOptimized: 153927 +// gas irOptimized: 153260 // gas legacy: 155961 // gas legacyOptimized: 153588 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage.sol b/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage.sol index f8dea7bbe..e90cf7e58 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage.sol @@ -15,6 +15,6 @@ contract C { // compileViaYul: also // ---- // f() -> 0 -// gas irOptimized: 135145 +// gas irOptimized: 135098 // gas legacy: 135313 // gas legacyOptimized: 134548 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage_packed.sol b/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage_packed.sol index b9e80c1d7..bd596b86c 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage_packed.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage_packed.sol @@ -42,11 +42,11 @@ contract C { // compileViaYul: also // ---- // f() -> 0 -// gas irOptimized: 92855 +// gas irOptimized: 92800 // gas legacy: 93006 // gas legacyOptimized: 92261 // g() -> 0 // h() -> 0 -// gas irOptimized: 92922 +// gas irOptimized: 92862 // gas legacy: 93028 // gas legacyOptimized: 92303 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_different_packing.sol b/test/libsolidity/semanticTests/array/copying/array_copy_different_packing.sol index 1cfbd1733..81607a264 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_different_packing.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_different_packing.sol @@ -21,6 +21,6 @@ contract c { // compileViaYul: also // ---- // test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000 -// gas irOptimized: 212669 +// gas irOptimized: 212571 // gas legacy: 221883 // gas legacyOptimized: 220734 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_including_array.sol b/test/libsolidity/semanticTests/array/copying/array_copy_including_array.sol index 2a58b9256..4f7023250 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_including_array.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_including_array.sol @@ -37,12 +37,12 @@ contract c { // compileViaYul: also // ---- // test() -> 0x02000202 -// gas irOptimized: 4660920 +// gas irOptimized: 4652092 // gas legacy: 4578341 // gas legacyOptimized: 4548354 // storageEmpty -> 1 // clear() -> 0, 0 -// gas irOptimized: 4491908 +// gas irOptimized: 4483169 // gas legacy: 4410769 // gas legacyOptimized: 4382531 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_nested_array.sol b/test/libsolidity/semanticTests/array/copying/array_copy_nested_array.sol index deb9404e3..0e05c4ea8 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_nested_array.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_nested_array.sol @@ -15,6 +15,6 @@ contract c { // compileViaYul: also // ---- // test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10 -// gas irOptimized: 690506 +// gas irOptimized: 690205 // gas legacy: 686268 // gas legacyOptimized: 685688 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base.sol index cee96209a..cad3c9d49 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base.sol @@ -19,6 +19,6 @@ contract c { // compileViaYul: also // ---- // test() -> 5, 4 -// gas irOptimized: 226130 +// gas irOptimized: 225956 // gas legacy: 233801 // gas legacyOptimized: 232816 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base_nested.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base_nested.sol index fcec284cc..4a475ac55 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base_nested.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base_nested.sol @@ -24,6 +24,6 @@ contract c { // compileViaYul: also // ---- // test() -> 3, 4 -// gas irOptimized: 190944 +// gas irOptimized: 190480 // gas legacy: 195353 // gas legacyOptimized: 192441 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dyn_dyn.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dyn_dyn.sol index 05e038378..202b3ad26 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dyn_dyn.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dyn_dyn.sol @@ -17,7 +17,7 @@ contract c { // ---- // setData1(uint256,uint256,uint256): 10, 5, 4 -> // copyStorageStorage() -> -// gas irOptimized: 111488 +// gas irOptimized: 111426 // gas legacy: 109278 // gas legacyOptimized: 109268 // getData2(uint256): 5 -> 10, 4 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dynamic_dynamic.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dynamic_dynamic.sol index 167e2740e..3b8fe6212 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dynamic_dynamic.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dynamic_dynamic.sol @@ -20,6 +20,6 @@ contract c { // compileViaYul: also // ---- // test() -> 5, 4 -// gas irOptimized: 272806 +// gas irOptimized: 272736 // gas legacy: 270834 // gas legacyOptimized: 269960 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_dynamic.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_dynamic.sol index 3b2ddbde1..d2d7f4e48 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_dynamic.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_dynamic.sol @@ -14,6 +14,6 @@ contract c { // compileViaYul: also // ---- // test() -> 9, 4 -// gas irOptimized: 123172 +// gas irOptimized: 123162 // gas legacy: 123579 // gas legacyOptimized: 123208 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_static.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_static.sol index 8d438013a..c865b8228 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_static.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_static.sol @@ -18,6 +18,6 @@ contract c { // compileViaYul: also // ---- // test() -> 8, 0 -// gas irOptimized: 236016 +// gas irOptimized: 236090 // gas legacy: 234695 // gas legacyOptimized: 234103 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_struct.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_struct.sol index 35776b6a1..db26b4d47 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_struct.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_struct.sol @@ -19,7 +19,7 @@ contract c { // compileViaYul: also // ---- // test() -> 4, 5 -// gas irOptimized: 239134 +// gas irOptimized: 238826 // gas legacy: 238736 // gas legacyOptimized: 237159 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_to_memory_nested.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_to_memory_nested.sol index 62f1ee715..3b2815526 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_to_memory_nested.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_to_memory_nested.sol @@ -17,6 +17,6 @@ contract C { // compileViaYul: also // ---- // f() -> 0x20, 2, 0x40, 0xa0, 2, 0, 1, 2, 2, 3 -// gas irOptimized: 161746 +// gas irOptimized: 161780 // gas legacy: 162278 // gas legacyOptimized: 159955 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover.sol b/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover.sol index 537924f14..1daa061a5 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover.sol @@ -20,6 +20,6 @@ contract c { // compileViaYul: also // ---- // test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000 -// gas irOptimized: 132180 +// gas irOptimized: 129167 // gas legacy: 186406 // gas legacyOptimized: 166126 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover2.sol b/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover2.sol index 36b387971..b42b84dfe 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover2.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover2.sol @@ -22,6 +22,6 @@ contract c { // compileViaYul: also // ---- // test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0 -// gas irOptimized: 93855 +// gas irOptimized: 93858 // gas legacy: 97451 // gas legacyOptimized: 94200 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_target_simple.sol b/test/libsolidity/semanticTests/array/copying/array_copy_target_simple.sol index b0387042f..c87f70244 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_target_simple.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_target_simple.sol @@ -22,6 +22,6 @@ contract c { // compileViaYul: also // ---- // test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0 -// gas irOptimized: 294958 +// gas irOptimized: 294772 // gas legacy: 303653 // gas legacyOptimized: 301999 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_target_simple_2.sol b/test/libsolidity/semanticTests/array/copying/array_copy_target_simple_2.sol index 893fbdba3..c39f80275 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_target_simple_2.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_target_simple_2.sol @@ -22,6 +22,6 @@ contract c { // compileViaYul: also // ---- // test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00 -// gas irOptimized: 274022 +// gas irOptimized: 273963 // gas legacy: 276381 // gas legacyOptimized: 275453 diff --git a/test/libsolidity/semanticTests/array/copying/array_nested_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/array_nested_calldata_to_storage.sol index 78f1bef9f..3cc9c9bd9 100644 --- a/test/libsolidity/semanticTests/array/copying/array_nested_calldata_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_nested_calldata_to_storage.sol @@ -38,10 +38,10 @@ contract c { // compileViaYul: true // ---- // test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65 -// gas irOptimized: 181755 +// gas irOptimized: 181308 // test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65 -// gas irOptimized: 158111 +// gas irOptimized: 157901 // test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65 -// gas irOptimized: 135282 +// gas irOptimized: 135108 // test4(uint256[2][2]): 23, 42, 23, 42 -> 65 -// gas irOptimized: 111460 +// gas irOptimized: 111428 diff --git a/test/libsolidity/semanticTests/array/copying/array_nested_memory_to_storage.sol b/test/libsolidity/semanticTests/array/copying/array_nested_memory_to_storage.sol index 707e25056..826d48b2b 100644 --- a/test/libsolidity/semanticTests/array/copying/array_nested_memory_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_nested_memory_to_storage.sol @@ -40,12 +40,12 @@ contract Test { // compileViaYul: also // ---- // test() -> 24 -// gas irOptimized: 227254 +// gas irOptimized: 227167 // gas legacy: 227133 // gas legacyOptimized: 226547 // test1() -> 3 // test2() -> 6 // test3() -> 24 -// gas irOptimized: 133753 +// gas irOptimized: 133621 // gas legacy: 134295 // gas legacyOptimized: 133383 diff --git a/test/libsolidity/semanticTests/array/copying/array_of_struct_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/array_of_struct_calldata_to_storage.sol index 27f81692c..b3d950ffa 100644 --- a/test/libsolidity/semanticTests/array/copying/array_of_struct_calldata_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_of_struct_calldata_to_storage.sol @@ -17,4 +17,4 @@ contract C { // compileViaYul: true // ---- // f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12 -// gas irOptimized: 121194 +// gas irOptimized: 121048 diff --git a/test/libsolidity/semanticTests/array/copying/array_of_struct_memory_to_storage.sol b/test/libsolidity/semanticTests/array/copying/array_of_struct_memory_to_storage.sol index 6f11f6c66..2fe271587 100644 --- a/test/libsolidity/semanticTests/array/copying/array_of_struct_memory_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_of_struct_memory_to_storage.sol @@ -19,4 +19,4 @@ contract C { // compileViaYul: true // ---- // f() -> 10, 11, 12 -// gas irOptimized: 119201 +// gas irOptimized: 119149 diff --git a/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_calldata_to_storage.sol index 970a5dced..7d4e1f845 100644 --- a/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_calldata_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_calldata_to_storage.sol @@ -23,4 +23,4 @@ contract C { // compileViaYul: true // ---- // f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1 -// gas irOptimized: 330385 +// gas irOptimized: 328592 diff --git a/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_memory_to_storage.sol b/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_memory_to_storage.sol index e4ff169f4..0b1d71bdf 100644 --- a/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_memory_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_memory_to_storage.sol @@ -26,4 +26,4 @@ contract C { // compileViaYul: true // ---- // f() -> 3, 3, 3, 1 -// gas irOptimized: 183411 +// gas irOptimized: 183316 diff --git a/test/libsolidity/semanticTests/array/copying/array_storage_multi_items_per_slot.sol b/test/libsolidity/semanticTests/array/copying/array_storage_multi_items_per_slot.sol index e23efb666..de38034fd 100644 --- a/test/libsolidity/semanticTests/array/copying/array_storage_multi_items_per_slot.sol +++ b/test/libsolidity/semanticTests/array/copying/array_storage_multi_items_per_slot.sol @@ -15,6 +15,6 @@ contract C { // compileViaYul: also // ---- // f() -> 1, 2, 3 -// gas irOptimized: 132580 +// gas irOptimized: 132298 // gas legacy: 134619 // gas legacyOptimized: 131940 diff --git a/test/libsolidity/semanticTests/array/copying/arrays_from_and_to_storage.sol b/test/libsolidity/semanticTests/array/copying/arrays_from_and_to_storage.sol index cee56c23b..dadbceadc 100644 --- a/test/libsolidity/semanticTests/array/copying/arrays_from_and_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/arrays_from_and_to_storage.sol @@ -12,7 +12,7 @@ contract Test { // compileViaYul: also // ---- // set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18 -// gas irOptimized: 99873 +// gas irOptimized: 99616 // gas legacy: 103563 // gas legacyOptimized: 101397 // data(uint256): 7 -> 8 diff --git a/test/libsolidity/semanticTests/array/copying/bytes_inside_mappings.sol b/test/libsolidity/semanticTests/array/copying/bytes_inside_mappings.sol index dd5f2a86a..809ef247d 100644 --- a/test/libsolidity/semanticTests/array/copying/bytes_inside_mappings.sol +++ b/test/libsolidity/semanticTests/array/copying/bytes_inside_mappings.sol @@ -7,11 +7,11 @@ contract c { // compileViaYul: also // ---- // set(uint256): 1, 2 -> true -// gas irOptimized: 110678 +// gas irOptimized: 110699 // gas legacy: 111091 // gas legacyOptimized: 110736 // set(uint256): 2, 2, 3, 4, 5 -> true -// gas irOptimized: 177635 +// gas irOptimized: 177659 // gas legacy: 178021 // gas legacyOptimized: 177666 // storageEmpty -> 0 diff --git a/test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol b/test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol index fb4e2159d..87974f053 100644 --- a/test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol @@ -19,25 +19,25 @@ contract c { // ---- // f(uint256): 0 -> 0x20, 0x00 // f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00 -// gas irOptimized: 125470 +// gas irOptimized: 121741 // gas legacy: 124364 // gas legacyOptimized: 119898 // f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671 -// gas irOptimized: 134121 +// gas irOptimized: 130733 // gas legacy: 135431 // gas legacyOptimized: 130829 // f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000 -// gas irOptimized: 141217 +// gas irOptimized: 137732 // gas legacy: 142238 // gas legacyOptimized: 137518 // f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992 -// gas irOptimized: 158957 +// gas irOptimized: 152352 // gas legacy: 160728 // gas legacyOptimized: 152168 // f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000 // gas legacy: 59345 // gas legacyOptimized: 57279 // f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968 -// gas irOptimized: 419485 +// gas irOptimized: 406089 // gas legacy: 423017 // gas legacyOptimized: 406021 diff --git a/test/libsolidity/semanticTests/array/copying/calldata_array_dynamic_to_storage.sol b/test/libsolidity/semanticTests/array/copying/calldata_array_dynamic_to_storage.sol index 7fba61c2c..7c0b3bdbb 100644 --- a/test/libsolidity/semanticTests/array/copying/calldata_array_dynamic_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/calldata_array_dynamic_to_storage.sol @@ -11,6 +11,6 @@ contract C { // compileViaYul: also // ---- // f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1 -// gas irOptimized: 111204 +// gas irOptimized: 111161 // gas legacy: 111565 // gas legacyOptimized: 111347 diff --git a/test/libsolidity/semanticTests/array/copying/copy_byte_array_in_struct_to_storage.sol b/test/libsolidity/semanticTests/array/copying/copy_byte_array_in_struct_to_storage.sol index 6bb47d9d9..ed0fe8f5f 100644 --- a/test/libsolidity/semanticTests/array/copying/copy_byte_array_in_struct_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/copy_byte_array_in_struct_to_storage.sol @@ -37,11 +37,11 @@ contract C { // compileViaYul: also // ---- // f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000 -// gas irOptimized: 179947 +// gas irOptimized: 179952 // gas legacy: 180694 // gas legacyOptimized: 180088 // g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000 -// gas irOptimized: 107322 +// gas irOptimized: 107332 // gas legacy: 107895 // gas legacyOptimized: 107254 // h() -> 0x40, 0x60, 0x00, 0x00 diff --git a/test/libsolidity/semanticTests/array/copying/copy_byte_array_to_storage.sol b/test/libsolidity/semanticTests/array/copying/copy_byte_array_to_storage.sol index 26332e6f2..b73f3dc44 100644 --- a/test/libsolidity/semanticTests/array/copying/copy_byte_array_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/copy_byte_array_to_storage.sol @@ -48,6 +48,6 @@ contract C { // compileViaYul: also // ---- // f() -> 0xff -// gas irOptimized: 121438 +// gas irOptimized: 121145 // gas legacy: 128035 // gas legacyOptimized: 123476 diff --git a/test/libsolidity/semanticTests/array/copying/copy_function_storage_array.sol b/test/libsolidity/semanticTests/array/copying/copy_function_storage_array.sol index 2401d90d9..8448d2e69 100644 --- a/test/libsolidity/semanticTests/array/copying/copy_function_storage_array.sol +++ b/test/libsolidity/semanticTests/array/copying/copy_function_storage_array.sol @@ -18,6 +18,6 @@ contract C { // compileViaYul: also // ---- // test() -> 7 -// gas irOptimized: 126212 +// gas irOptimized: 126552 // gas legacy: 205196 // gas legacyOptimized: 204987 diff --git a/test/libsolidity/semanticTests/array/copying/copy_removes_bytes_data.sol b/test/libsolidity/semanticTests/array/copying/copy_removes_bytes_data.sol index 2532c04af..b8ec0d97f 100644 --- a/test/libsolidity/semanticTests/array/copying/copy_removes_bytes_data.sol +++ b/test/libsolidity/semanticTests/array/copying/copy_removes_bytes_data.sol @@ -9,7 +9,7 @@ contract c { // compileViaYul: also // ---- // set(): 1, 2, 3, 4, 5 -> true -// gas irOptimized: 177396 +// gas irOptimized: 177417 // gas legacy: 177656 // gas legacyOptimized: 177496 // storageEmpty -> 0 diff --git a/test/libsolidity/semanticTests/array/copying/memory_dyn_2d_bytes_to_storage.sol b/test/libsolidity/semanticTests/array/copying/memory_dyn_2d_bytes_to_storage.sol index 5cb657afe..3d4623b79 100644 --- a/test/libsolidity/semanticTests/array/copying/memory_dyn_2d_bytes_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/memory_dyn_2d_bytes_to_storage.sol @@ -20,6 +20,6 @@ contract C { // compileViaYul: also // ---- // f() -> 3 -// gas irOptimized: 131095 +// gas irOptimized: 129916 // gas legacy: 130307 // gas legacyOptimized: 129363 diff --git a/test/libsolidity/semanticTests/array/copying/storage_memory_nested.sol b/test/libsolidity/semanticTests/array/copying/storage_memory_nested.sol index 9f325200d..ec58360cd 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_nested.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_nested.sol @@ -19,6 +19,6 @@ contract C { // compileViaYul: also // ---- // f() -> 1, 2, 3, 4, 5, 6, 7 -// gas irOptimized: 207030 +// gas irOptimized: 207785 // gas legacy: 212325 // gas legacyOptimized: 211486 diff --git a/test/libsolidity/semanticTests/array/copying/storage_memory_nested_bytes.sol b/test/libsolidity/semanticTests/array/copying/storage_memory_nested_bytes.sol index 5749e3ad8..f94b442f3 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_nested_bytes.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_nested_bytes.sol @@ -13,6 +13,6 @@ contract C { // compileViaYul: also // ---- // f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000 -// gas irOptimized: 202750 +// gas irOptimized: 202840 // gas legacy: 204459 // gas legacyOptimized: 203437 diff --git a/test/libsolidity/semanticTests/array/copying/storage_memory_nested_from_pointer.sol b/test/libsolidity/semanticTests/array/copying/storage_memory_nested_from_pointer.sol index 8893bd94d..ece6f7969 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_nested_from_pointer.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_nested_from_pointer.sol @@ -20,6 +20,6 @@ contract C { // compileViaYul: also // ---- // f() -> 1, 2, 3, 4, 5, 6, 7 -// gas irOptimized: 207030 +// gas irOptimized: 207785 // gas legacy: 212330 // gas legacyOptimized: 211491 diff --git a/test/libsolidity/semanticTests/array/copying/storage_memory_nested_struct.sol b/test/libsolidity/semanticTests/array/copying/storage_memory_nested_struct.sol index 2e1a2cc3c..556fb5a61 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_nested_struct.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_nested_struct.sol @@ -26,6 +26,6 @@ contract C { // compileViaYul: also // ---- // f() -> 11, 0x0c, 1, 0x15, 22, 4 -// gas irOptimized: 291923 +// gas irOptimized: 291850 // gas legacy: 293516 // gas legacyOptimized: 290263 diff --git a/test/libsolidity/semanticTests/array/copying/storage_memory_packed_dyn.sol b/test/libsolidity/semanticTests/array/copying/storage_memory_packed_dyn.sol index caf1e1dfd..abcd72ee1 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_packed_dyn.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_packed_dyn.sol @@ -15,6 +15,6 @@ contract C { // compileViaYul: also // ---- // f() -> 2, 3, 4 -// gas irOptimized: 114568 +// gas irOptimized: 114120 // gas legacy: 126449 // gas legacyOptimized: 120902 diff --git a/test/libsolidity/semanticTests/array/create_memory_array.sol b/test/libsolidity/semanticTests/array/create_memory_array.sol index adc51585a..8072526ab 100644 --- a/test/libsolidity/semanticTests/array/create_memory_array.sol +++ b/test/libsolidity/semanticTests/array/create_memory_array.sol @@ -20,6 +20,6 @@ contract C { // compileViaYul: also // ---- // f() -> "A", 8, 4, "B" -// gas irOptimized: 140716 +// gas irOptimized: 130594 // gas legacy: 121398 // gas legacyOptimized: 115494 diff --git a/test/libsolidity/semanticTests/array/delete/bytes_delete_element.sol b/test/libsolidity/semanticTests/array/delete/bytes_delete_element.sol index f3c4a87b4..149e8768d 100644 --- a/test/libsolidity/semanticTests/array/delete/bytes_delete_element.sol +++ b/test/libsolidity/semanticTests/array/delete/bytes_delete_element.sol @@ -18,6 +18,6 @@ contract c { // compileViaYul: also // ---- // test1() -> true -// gas irOptimized: 230748 +// gas irOptimized: 225894 // gas legacy: 255577 // gas legacyOptimized: 248611 diff --git a/test/libsolidity/semanticTests/array/delete/delete_storage_array_packed.sol b/test/libsolidity/semanticTests/array/delete/delete_storage_array_packed.sol index 36a2eca41..82c8d6b6c 100644 --- a/test/libsolidity/semanticTests/array/delete/delete_storage_array_packed.sol +++ b/test/libsolidity/semanticTests/array/delete/delete_storage_array_packed.sol @@ -16,4 +16,4 @@ contract C { // compileViaYul: also // ---- // f() -> 0, 0, 0 -// gas irOptimized: 91245 +// gas irOptimized: 91098 diff --git a/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol b/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol index 46e3606ba..9f4be2119 100644 --- a/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol +++ b/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol @@ -16,7 +16,7 @@ contract c { // ---- // storageEmpty -> 1 // fill() -> -// gas irOptimized: 520360 +// gas irOptimized: 519848 // gas legacy: 521773 // gas legacyOptimized: 517048 // storageEmpty -> 0 diff --git a/test/libsolidity/semanticTests/array/dynamic_arrays_in_storage.sol b/test/libsolidity/semanticTests/array/dynamic_arrays_in_storage.sol index f95a93a22..2587442d5 100644 --- a/test/libsolidity/semanticTests/array/dynamic_arrays_in_storage.sol +++ b/test/libsolidity/semanticTests/array/dynamic_arrays_in_storage.sol @@ -44,7 +44,7 @@ contract c { // ---- // getLengths() -> 0, 0 // setLengths(uint256,uint256): 48, 49 -> -// gas irOptimized: 104851 +// gas irOptimized: 104355 // gas legacy: 108571 // gas legacyOptimized: 100417 // getLengths() -> 48, 49 diff --git a/test/libsolidity/semanticTests/array/dynamic_multi_array_cleanup.sol b/test/libsolidity/semanticTests/array/dynamic_multi_array_cleanup.sol index 7d7f4188b..6aecbde32 100644 --- a/test/libsolidity/semanticTests/array/dynamic_multi_array_cleanup.sol +++ b/test/libsolidity/semanticTests/array/dynamic_multi_array_cleanup.sol @@ -18,7 +18,7 @@ contract c { // ---- // storageEmpty -> 1 // fill() -> 8 -// gas irOptimized: 123113 +// gas irOptimized: 122528 // gas legacy: 121756 // gas legacyOptimized: 120687 // storageEmpty -> 0 diff --git a/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol b/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol index c5a63fa3a..dd131f287 100644 --- a/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol +++ b/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol @@ -13,7 +13,7 @@ contract c { // ---- // storageEmpty -> 1 // fill() -> -// gas irOptimized: 465690 +// gas irOptimized: 465585 // gas legacy: 471460 // gas legacyOptimized: 467520 // storageEmpty -> 0 diff --git a/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol b/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol index ab9ae1640..5e30621af 100644 --- a/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol +++ b/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol @@ -21,6 +21,6 @@ contract B { // compileViaYul: also // ---- // f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004 -// gas irOptimized: 120848 +// gas irOptimized: 130328 // gas legacy: 235199 // gas legacyOptimized: 133119 diff --git a/test/libsolidity/semanticTests/array/function_array_cross_calls.sol b/test/libsolidity/semanticTests/array/function_array_cross_calls.sol index 6545dc900..95cb52f11 100644 --- a/test/libsolidity/semanticTests/array/function_array_cross_calls.sol +++ b/test/libsolidity/semanticTests/array/function_array_cross_calls.sol @@ -45,6 +45,6 @@ contract C { // compileViaYul: also // ---- // test() -> 5, 6, 7 -// gas irOptimized: 297690 +// gas irOptimized: 302321 // gas legacy: 462080 // gas legacyOptimized: 294938 diff --git a/test/libsolidity/semanticTests/array/pop/array_pop_array_transition.sol b/test/libsolidity/semanticTests/array/pop/array_pop_array_transition.sol index 9788b6136..f2a98f993 100644 --- a/test/libsolidity/semanticTests/array/pop/array_pop_array_transition.sol +++ b/test/libsolidity/semanticTests/array/pop/array_pop_array_transition.sol @@ -25,7 +25,7 @@ contract c { // compileViaYul: also // ---- // test() -> 1, 2, 3 -// gas irOptimized: 2272395 +// gas irOptimized: 2271482 // gas legacy: 2273722 // gas legacyOptimized: 2262396 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/pop/array_pop_uint16_transition.sol b/test/libsolidity/semanticTests/array/pop/array_pop_uint16_transition.sol index 3ad0d8f32..4be29a15d 100644 --- a/test/libsolidity/semanticTests/array/pop/array_pop_uint16_transition.sol +++ b/test/libsolidity/semanticTests/array/pop/array_pop_uint16_transition.sol @@ -20,7 +20,7 @@ contract c { // compileViaYul: also // ---- // test() -> 38, 28, 18 -// gas irOptimized: 192323 +// gas irOptimized: 188649 // gas legacy: 189780 // gas legacyOptimized: 178870 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/pop/array_pop_uint24_transition.sol b/test/libsolidity/semanticTests/array/pop/array_pop_uint24_transition.sol index dc3b2a861..08a403174 100644 --- a/test/libsolidity/semanticTests/array/pop/array_pop_uint24_transition.sol +++ b/test/libsolidity/semanticTests/array/pop/array_pop_uint24_transition.sol @@ -20,7 +20,7 @@ contract c { // compileViaYul: also // ---- // test() -> 20, 10 -// gas irOptimized: 161105 +// gas irOptimized: 159175 // gas legacy: 159459 // gas legacyOptimized: 153281 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/pop/byte_array_pop_copy_long.sol b/test/libsolidity/semanticTests/array/pop/byte_array_pop_copy_long.sol index 2b893c668..387d21872 100644 --- a/test/libsolidity/semanticTests/array/pop/byte_array_pop_copy_long.sol +++ b/test/libsolidity/semanticTests/array/pop/byte_array_pop_copy_long.sol @@ -12,6 +12,6 @@ contract c { // compileViaYul: also // ---- // test() -> 0x20, 29, 0x0303030303030303030303030303030303030303030303030303030303000000 -// gas irOptimized: 111157 +// gas irOptimized: 109503 // gas legacy: 127309 // gas legacyOptimized: 124136 diff --git a/test/libsolidity/semanticTests/array/pop/byte_array_pop_long_storage_empty.sol b/test/libsolidity/semanticTests/array/pop/byte_array_pop_long_storage_empty.sol index bf605984b..c911b1b7c 100644 --- a/test/libsolidity/semanticTests/array/pop/byte_array_pop_long_storage_empty.sol +++ b/test/libsolidity/semanticTests/array/pop/byte_array_pop_long_storage_empty.sol @@ -18,7 +18,7 @@ contract c { // compileViaYul: also // ---- // test() -> true -// gas irOptimized: 205254 +// gas irOptimized: 196545 // gas legacy: 229864 // gas legacyOptimized: 210964 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/pop/byte_array_pop_long_storage_empty_garbage_ref.sol b/test/libsolidity/semanticTests/array/pop/byte_array_pop_long_storage_empty_garbage_ref.sol index 09e65f0c5..38c0c84d6 100644 --- a/test/libsolidity/semanticTests/array/pop/byte_array_pop_long_storage_empty_garbage_ref.sol +++ b/test/libsolidity/semanticTests/array/pop/byte_array_pop_long_storage_empty_garbage_ref.sol @@ -17,7 +17,7 @@ contract c { // compileViaYul: also // ---- // test() -> -// gas irOptimized: 146450 +// gas irOptimized: 142640 // gas legacy: 165363 // gas legacyOptimized: 159446 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/pop/byte_array_pop_masking_long.sol b/test/libsolidity/semanticTests/array/pop/byte_array_pop_masking_long.sol index ca5909722..6d314fb27 100644 --- a/test/libsolidity/semanticTests/array/pop/byte_array_pop_masking_long.sol +++ b/test/libsolidity/semanticTests/array/pop/byte_array_pop_masking_long.sol @@ -12,6 +12,6 @@ contract c { // compileViaYul: also // ---- // test() -> 0x20, 33, 0x303030303030303030303030303030303030303030303030303030303030303, 0x0300000000000000000000000000000000000000000000000000000000000000 -// gas irOptimized: 109314 +// gas irOptimized: 108493 // gas legacy: 126187 // gas legacyOptimized: 123261 diff --git a/test/libsolidity/semanticTests/array/push/array_push.sol b/test/libsolidity/semanticTests/array/push/array_push.sol index 83cceeb56..e8ec36639 100644 --- a/test/libsolidity/semanticTests/array/push/array_push.sol +++ b/test/libsolidity/semanticTests/array/push/array_push.sol @@ -18,6 +18,6 @@ contract c { // compileViaYul: also // ---- // test() -> 5, 4, 3, 3 -// gas irOptimized: 111289 +// gas irOptimized: 111317 // gas legacy: 111838 // gas legacyOptimized: 111128 diff --git a/test/libsolidity/semanticTests/array/push/array_push_nested_from_calldata.sol b/test/libsolidity/semanticTests/array/push/array_push_nested_from_calldata.sol index 39f99a9bd..a4be5ad90 100644 --- a/test/libsolidity/semanticTests/array/push/array_push_nested_from_calldata.sol +++ b/test/libsolidity/semanticTests/array/push/array_push_nested_from_calldata.sol @@ -14,6 +14,6 @@ contract C { // compileViaYul: also // ---- // f(uint120[]): 0x20, 3, 1, 2, 3 -> 1 -// gas irOptimized: 113393 +// gas irOptimized: 113267 // gas legacy: 113686 // gas legacyOptimized: 113499 diff --git a/test/libsolidity/semanticTests/array/push/array_push_packed_array.sol b/test/libsolidity/semanticTests/array/push/array_push_packed_array.sol index 72ab9ea14..04f9544a9 100644 --- a/test/libsolidity/semanticTests/array/push/array_push_packed_array.sol +++ b/test/libsolidity/semanticTests/array/push/array_push_packed_array.sol @@ -16,6 +16,6 @@ contract c { // compileViaYul: also // ---- // test() -> 1, 2, 3, 4 -// gas irOptimized: 93200 +// gas irOptimized: 93017 // gas legacy: 92798 // gas legacyOptimized: 92062 diff --git a/test/libsolidity/semanticTests/array/push/array_push_struct.sol b/test/libsolidity/semanticTests/array/push/array_push_struct.sol index 03a2c53b3..60e317770 100644 --- a/test/libsolidity/semanticTests/array/push/array_push_struct.sol +++ b/test/libsolidity/semanticTests/array/push/array_push_struct.sol @@ -22,6 +22,6 @@ contract c { // compileViaYul: also // ---- // test() -> 2, 3, 4, 5 -// gas irOptimized: 137074 +// gas irOptimized: 136894 // gas legacy: 147484 // gas legacyOptimized: 146456 diff --git a/test/libsolidity/semanticTests/array/push/array_push_struct_from_calldata.sol b/test/libsolidity/semanticTests/array/push/array_push_struct_from_calldata.sol index 272b179e9..f6da6a398 100644 --- a/test/libsolidity/semanticTests/array/push/array_push_struct_from_calldata.sol +++ b/test/libsolidity/semanticTests/array/push/array_push_struct_from_calldata.sol @@ -18,6 +18,6 @@ contract c { // compileViaYul: also // ---- // test((uint16,uint16,uint16[3],uint16[])): 0x20, 2, 3, 0, 0, 4, 0xC0, 4, 0, 0, 5, 0, 0 -> 2, 3, 4, 5 -// gas irOptimized: 139100 +// gas irOptimized: 138785 // gas legacy: 145150 // gas legacyOptimized: 139171 diff --git a/test/libsolidity/semanticTests/array/push/byte_array_push_transition.sol b/test/libsolidity/semanticTests/array/push/byte_array_push_transition.sol index 86ef51a81..78c817d44 100644 --- a/test/libsolidity/semanticTests/array/push/byte_array_push_transition.sol +++ b/test/libsolidity/semanticTests/array/push/byte_array_push_transition.sol @@ -17,6 +17,6 @@ contract c { // compileViaYul: also // ---- // test() -> 0 -// gas irOptimized: 185231 +// gas irOptimized: 176848 // gas legacy: 218028 // gas legacyOptimized: 205124 diff --git a/test/libsolidity/semanticTests/array/push/nested_bytes_push.sol b/test/libsolidity/semanticTests/array/push/nested_bytes_push.sol index f1a245ce4..262ba724a 100644 --- a/test/libsolidity/semanticTests/array/push/nested_bytes_push.sol +++ b/test/libsolidity/semanticTests/array/push/nested_bytes_push.sol @@ -15,6 +15,6 @@ contract C { // compileViaYul: also // ---- // f() -> -// gas irOptimized: 179867 +// gas irOptimized: 179590 // gas legacy: 180620 // gas legacyOptimized: 180403 diff --git a/test/libsolidity/semanticTests/array/push/push_no_args_2d.sol b/test/libsolidity/semanticTests/array/push/push_no_args_2d.sol index fe6138a4a..8df809acd 100644 --- a/test/libsolidity/semanticTests/array/push/push_no_args_2d.sol +++ b/test/libsolidity/semanticTests/array/push/push_no_args_2d.sol @@ -29,14 +29,14 @@ contract C { // ---- // l() -> 0 // f(uint256,uint256): 42, 64 -> -// gas irOptimized: 114151 +// gas irOptimized: 112555 // gas legacy: 108234 // gas legacyOptimized: 102245 // l() -> 1 // ll(uint256): 0 -> 43 // a(uint256,uint256): 0, 42 -> 64 // f(uint256,uint256): 84, 128 -> -// gas irOptimized: 119535 +// gas irOptimized: 116427 // gas legacy: 107780 // gas legacyOptimized: 96331 // l() -> 2 diff --git a/test/libsolidity/semanticTests/array/push/push_no_args_bytes.sol b/test/libsolidity/semanticTests/array/push/push_no_args_bytes.sol index 093d3aa5a..defbf4149 100644 --- a/test/libsolidity/semanticTests/array/push/push_no_args_bytes.sol +++ b/test/libsolidity/semanticTests/array/push/push_no_args_bytes.sol @@ -23,7 +23,7 @@ contract C { // ---- // l() -> 0 // g(uint256): 70 -> -// gas irOptimized: 191389 +// gas irOptimized: 184507 // gas legacy: 184991 // gas legacyOptimized: 180608 // l() -> 70 diff --git a/test/libsolidity/semanticTests/array/reusing_memory.sol b/test/libsolidity/semanticTests/array/reusing_memory.sol index 7ae96a3d6..7d2b4d995 100644 --- a/test/libsolidity/semanticTests/array/reusing_memory.sol +++ b/test/libsolidity/semanticTests/array/reusing_memory.sol @@ -26,6 +26,6 @@ contract Main { // compileViaYul: also // ---- // f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1 -// gas irOptimized: 113954 +// gas irOptimized: 113776 // gas legacy: 126852 // gas legacyOptimized: 114079 diff --git a/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol b/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol index c55ce061d..63c2acbb5 100644 --- a/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol +++ b/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol @@ -26,6 +26,6 @@ contract Creator { // compileViaYul: also // ---- // f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8 -// gas irOptimized: 458295 +// gas irOptimized: 456873 // gas legacy: 590939 // gas legacyOptimized: 448582 diff --git a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol index c0123af13..d4d41d80c 100644 --- a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol +++ b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol @@ -26,6 +26,6 @@ contract Creator { // compileViaYul: also // ---- // f(uint256,bytes): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> 7, "h" -// gas irOptimized: 312176 +// gas irOptimized: 308702 // gas legacy: 429173 // gas legacyOptimized: 298384 diff --git a/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol b/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol index 3bf97c49b..3fdbb0785 100644 --- a/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol +++ b/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol @@ -19,6 +19,6 @@ contract C { // compileViaYul: also // ---- // f(), 2000 ether -> true -// gas irOptimized: 123090 +// gas irOptimized: 123037 // gas legacy: 123226 // gas legacyOptimized: 123092 diff --git a/test/libsolidity/semanticTests/events/event_dynamic_array_storage.sol b/test/libsolidity/semanticTests/events/event_dynamic_array_storage.sol index 2da24603e..b5db5ca2b 100644 --- a/test/libsolidity/semanticTests/events/event_dynamic_array_storage.sol +++ b/test/libsolidity/semanticTests/events/event_dynamic_array_storage.sol @@ -15,6 +15,6 @@ contract C { // ---- // createEvent(uint256): 42 -> // ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c -// gas irOptimized: 114816 +// gas irOptimized: 114746 // gas legacy: 116393 // gas legacyOptimized: 114415 diff --git a/test/libsolidity/semanticTests/events/event_dynamic_array_storage_v2.sol b/test/libsolidity/semanticTests/events/event_dynamic_array_storage_v2.sol index 8e02a5bfc..f833ba37a 100644 --- a/test/libsolidity/semanticTests/events/event_dynamic_array_storage_v2.sol +++ b/test/libsolidity/semanticTests/events/event_dynamic_array_storage_v2.sol @@ -16,6 +16,6 @@ contract C { // ---- // createEvent(uint256): 42 -> // ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c -// gas irOptimized: 114816 +// gas irOptimized: 114746 // gas legacy: 116393 // gas legacyOptimized: 114415 diff --git a/test/libsolidity/semanticTests/events/event_dynamic_nested_array_storage_v2.sol b/test/libsolidity/semanticTests/events/event_dynamic_nested_array_storage_v2.sol index f9e773b75..552444dd8 100644 --- a/test/libsolidity/semanticTests/events/event_dynamic_nested_array_storage_v2.sol +++ b/test/libsolidity/semanticTests/events/event_dynamic_nested_array_storage_v2.sol @@ -17,6 +17,6 @@ contract C { // ---- // createEvent(uint256): 42 -> // ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d -// gas irOptimized: 185564 +// gas irOptimized: 185444 // gas legacy: 187621 // gas legacyOptimized: 184551 diff --git a/test/libsolidity/semanticTests/events/event_indexed_mixed.sol b/test/libsolidity/semanticTests/events/event_indexed_mixed.sol index d3971c1e9..47aca1e2a 100644 --- a/test/libsolidity/semanticTests/events/event_indexed_mixed.sol +++ b/test/libsolidity/semanticTests/events/event_indexed_mixed.sol @@ -13,6 +13,6 @@ contract C { // ---- // deposit() -> // ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, "def" -// gas irOptimized: 23685 +// gas irOptimized: 23709 // gas legacy: 24342 // gas legacyOptimized: 23753 diff --git a/test/libsolidity/semanticTests/events/event_indexed_string.sol b/test/libsolidity/semanticTests/events/event_indexed_string.sol index a411da3c6..d35db93c4 100644 --- a/test/libsolidity/semanticTests/events/event_indexed_string.sol +++ b/test/libsolidity/semanticTests/events/event_indexed_string.sol @@ -19,6 +19,6 @@ contract C { // ---- // deposit() -> // ~ emit E(string,uint256[4]): #0xa7fb06bb999a5eb9aff9e0779953f4e1e4ce58044936c2f51c7fb879b85c08bd, #0xe755d8cc1a8cde16a2a31160dcd8017ac32d7e2f13215b29a23cdae40a78aa81 -// gas irOptimized: 353515 +// gas irOptimized: 343396 // gas legacy: 390742 // gas legacyOptimized: 376774 diff --git a/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol b/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol index b7be3cf05..9205de434 100644 --- a/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol +++ b/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol @@ -76,12 +76,12 @@ contract FixedFeeRegistrar is Registrar { // compileViaYul: also // ---- // constructor() -// gas irOptimized: 433748 +// gas irOptimized: 425623 // gas legacy: 936897 -// gas legacyOptimized: 491019 +// gas legacyOptimized: 490983 // reserve(string), 69 ether: 0x20, 3, "abc" -> // ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 -// gas irOptimized: 46070 +// gas irOptimized: 45967 // gas legacy: 46842 // gas legacyOptimized: 46091 // owner(string): 0x20, 3, "abc" -> 0x1212121212121212121212121212120000000012 diff --git a/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol b/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol index 81efd3566..f054497e9 100644 --- a/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol +++ b/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol @@ -178,7 +178,7 @@ contract DepositContract is IDepositContract, ERC165 { // compileViaYul: also // ---- // constructor() -// gas irOptimized: 1657475 +// gas irOptimized: 1558013 // gas legacy: 2580394 // gas legacyOptimized: 1775403 // supportsInterface(bytes4): 0x0 -> 0 @@ -186,27 +186,27 @@ contract DepositContract is IDepositContract, ERC165 { // supportsInterface(bytes4): 0x01ffc9a700000000000000000000000000000000000000000000000000000000 -> true # ERC-165 id # // supportsInterface(bytes4): 0x8564090700000000000000000000000000000000000000000000000000000000 -> true # the deposit interface id # // get_deposit_root() -> 0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e -// gas irOptimized: 122599 +// gas irOptimized: 122169 // gas legacy: 150465 // gas legacyOptimized: 122798 // get_deposit_count() -> 0x20, 8, 0 # TODO: check balance and logs after each deposit # // deposit(bytes,bytes,bytes,bytes32), 32 ether: 0 -> FAILURE # Empty input # // get_deposit_root() -> 0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e -// gas irOptimized: 122599 +// gas irOptimized: 122169 // gas legacy: 150465 // gas legacyOptimized: 122798 // get_deposit_count() -> 0x20, 8, 0 // deposit(bytes,bytes,bytes,bytes32), 1 ether: 0x80, 0xe0, 0x120, 0xaa4a8d0b7d9077248630f1a4701ae9764e42271d7f22b7838778411857fd349e, 0x30, 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f73292, 0x67a8811c397529dac52ae1342ba58c9500000000000000000000000000000000, 0x20, 0x00f50428677c60f997aadeab24aabf7fceaef491c96a52b463ae91f95611cf71, 0x60, 0xa29d01cc8c6296a8150e515b5995390ef841dc18948aa3e79be6d7c1851b4cbb, 0x5d6ff49fa70b9c782399506a22a85193151b9b691245cebafd2063012443c132, 0x4b6c36debaedefb7b2d71b0503ffdc00150aaffd42e63358238ec888901738b8 -> # txhash: 0x7085c586686d666e8bb6e9477a0f0b09565b2060a11f1c4209d3a52295033832 # // ~ 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 // get_deposit_root() -> 0x2089653123d9c721215120b6db6738ba273bbc5228ac093b1f983badcdc8a438 -// gas irOptimized: 122606 +// gas irOptimized: 122148 // gas legacy: 150475 // gas legacyOptimized: 122811 // get_deposit_count() -> 0x20, 8, 0x0100000000000000000000000000000000000000000000000000000000000000 // deposit(bytes,bytes,bytes,bytes32), 32 ether: 0x80, 0xe0, 0x120, 0xdbd986dc85ceb382708cf90a3500f500f0a393c5ece76963ac3ed72eccd2c301, 0x30, 0xb2ce0f79f90e7b3a113ca5783c65756f96c4b4673c2b5c1eb4efc22280259441, 0x06d601211e8866dc5b50dc48a244dd7c00000000000000000000000000000000, 0x20, 0x00344b6c73f71b11c56aba0d01b7d8ad83559f209d0a4101a515f6ad54c89771, 0x60, 0x945caaf82d18e78c033927d51f452ebcd76524497b91d7a11219cb3db6a1d369, 0x7595fc095ce489e46b2ef129591f2f6d079be4faaf345a02c5eb133c072e7c56, 0x0c6c3617eee66b4b878165c502357d49485326bc6b31bc96873f308c8f19c09d -> # txhash: 0x404d8e109822ce448e68f45216c12cb051b784d068fbe98317ab8e50c58304ac # // ~ 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 // get_deposit_root() -> 0x40255975859377d912c53aa853245ebd939bdd2b33a28e084babdcc1ed8238ee -// gas irOptimized: 122606 +// gas irOptimized: 122148 // gas legacy: 150475 // gas legacyOptimized: 122811 // get_deposit_count() -> 0x20, 8, 0x0200000000000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol b/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol index 77be50301..01d2403a6 100644 --- a/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol +++ b/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol @@ -50,46 +50,46 @@ contract test { // compileViaYul: also // ---- // constructor() -// gas irOptimized: 1965559 +// gas irOptimized: 1924584 // gas legacy: 2602700 // gas legacyOptimized: 1874490 // div(int256,int256): 3141592653589793238, 88714123 -> 35412542528203691288251815328 -// gas irOptimized: 22244 +// gas irOptimized: 22137 // gas legacy: 22767 // gas legacyOptimized: 22282 // exp(int256): 3141592653589793238 -> 23140692632779268978 -// gas irOptimized: 24358 +// gas irOptimized: 24545 // gas legacy: 25203 // gas legacyOptimized: 24357 // exp2(int256): 3141592653589793238 -> 8824977827076287620 -// gas irOptimized: 24125 +// gas irOptimized: 24257 // gas legacy: 24864 // gas legacyOptimized: 24110 // gm(int256,int256): 3141592653589793238, 88714123 -> 16694419339601 -// gas irOptimized: 23057 +// gas irOptimized: 22970 // gas legacy: 23228 // gas legacyOptimized: 22683 // log10(int256): 3141592653589793238 -> 4971498726941338506 -// gas irOptimized: 30112 +// gas irOptimized: 30609 // gas legacy: 32934 // gas legacyOptimized: 30323 // log2(int256): 3141592653589793238 -> 1651496129472318782 -// gas irOptimized: 28300 +// gas irOptimized: 28819 // gas legacy: 31067 // gas legacyOptimized: 28426 // mul(int256,int256): 3141592653589793238, 88714123 -> 278703637 -// gas irOptimized: 22335 +// gas irOptimized: 22225 // gas legacy: 22807 // gas legacyOptimized: 22295 // pow(int256,uint256): 3141592653589793238, 5 -> 306019684785281453040 -// gas irOptimized: 22861 +// gas irOptimized: 22635 // gas legacy: 23508 // gas legacyOptimized: 22921 // sqrt(int256): 3141592653589793238 -> 1772453850905516027 -// gas irOptimized: 22702 +// gas irOptimized: 22650 // gas legacy: 22802 // gas legacyOptimized: 22422 // benchmark(int256): 3141592653589793238 -> 998882724338592125, 1000000000000000000, 1000000000000000000 -// gas irOptimized: 37899 +// gas irOptimized: 36630 // gas legacy: 36673 // gas legacyOptimized: 34729 diff --git a/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol b/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol index 8a096f524..c31664c85 100644 --- a/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol +++ b/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol @@ -50,46 +50,46 @@ contract test { // compileViaYul: also // ---- // constructor() -// gas irOptimized: 1769431 +// gas irOptimized: 1778342 // gas legacy: 2356230 // gas legacyOptimized: 1746528 // div(uint256,uint256): 3141592653589793238, 88714123 -> 35412542528203691288251815328 -// gas irOptimized: 22047 +// gas irOptimized: 22004 // gas legacy: 22497 // gas legacyOptimized: 22010 // exp(uint256): 3141592653589793238 -> 23140692632779268978 -// gas irOptimized: 24234 +// gas irOptimized: 24444 // gas legacy: 25104 // gas legacyOptimized: 24258 // exp2(uint256): 3141592653589793238 -> 8824977827076287620 -// gas irOptimized: 24063 +// gas irOptimized: 24198 // gas legacy: 24814 // gas legacyOptimized: 24062 // gm(uint256,uint256): 3141592653589793238, 88714123 -> 16694419339601 -// gas irOptimized: 23036 +// gas irOptimized: 22950 // gas legacy: 23269 // gas legacyOptimized: 22724 // log10(uint256): 3141592653589793238 -> 0x44fe4fc084a52b8a -// gas irOptimized: 29892 +// gas irOptimized: 30269 // gas legacy: 32898 // gas legacyOptimized: 29925 // log2(uint256): 3141592653589793238 -> 1651496129472318782 -// gas irOptimized: 27822 +// gas irOptimized: 28235 // gas legacy: 30986 // gas legacyOptimized: 28001 // mul(uint256,uint256): 3141592653589793238, 88714123 -> 278703637 -// gas irOptimized: 22094 +// gas irOptimized: 22048 // gas legacy: 22604 // gas legacyOptimized: 22090 // pow(uint256,uint256): 3141592653589793238, 5 -> 306019684785281453040 -// gas irOptimized: 22565 +// gas irOptimized: 22406 // gas legacy: 23245 // gas legacyOptimized: 22646 // sqrt(uint256): 3141592653589793238 -> 1772453850905516027 -// gas irOptimized: 22720 +// gas irOptimized: 22672 // gas legacy: 22820 // gas legacyOptimized: 22440 // benchmark(uint256): 3141592653589793238 -> 998882724338592125, 1000000000000000000, 1000000000000000000 -// gas irOptimized: 36587 +// gas irOptimized: 35603 // gas legacy: 35385 // gas legacyOptimized: 33449 diff --git a/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol b/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol index 2c9376b22..1fc85adff 100644 --- a/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol +++ b/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol @@ -35,10 +35,10 @@ contract test { // compileViaYul: also // ---- // constructor() -// gas irOptimized: 528041 +// gas irOptimized: 465357 // gas legacy: 733634 // gas legacyOptimized: 479606 // prb_pi() -> 3141592656369545286 -// gas irOptimized: 63027 +// gas irOptimized: 57478 // gas legacy: 98903 // gas legacyOptimized: 75735 diff --git a/test/libsolidity/semanticTests/externalContracts/snark.sol b/test/libsolidity/semanticTests/externalContracts/snark.sol index 7a7b95695..8f6b939fd 100644 --- a/test/libsolidity/semanticTests/externalContracts/snark.sol +++ b/test/libsolidity/semanticTests/externalContracts/snark.sol @@ -297,6 +297,6 @@ contract Test { // pair() -> true // verifyTx() -> true // ~ emit Verified(string): 0x20, 0x16, "Successfully verified." -// gas irOptimized: 101054 +// gas irOptimized: 95261 // gas legacy: 114094 // gas legacyOptimized: 83670 diff --git a/test/libsolidity/semanticTests/externalContracts/strings.sol b/test/libsolidity/semanticTests/externalContracts/strings.sol index 1fa79f382..238ed2184 100644 --- a/test/libsolidity/semanticTests/externalContracts/strings.sol +++ b/test/libsolidity/semanticTests/externalContracts/strings.sol @@ -51,26 +51,26 @@ contract test { // compileViaYul: also // ---- // constructor() -// gas irOptimized: 778254 +// gas irOptimized: 702619 // gas legacy: 1188228 // gas legacyOptimized: 750416 // toSlice(string): 0x20, 11, "hello world" -> 11, 0xa0 -// gas irOptimized: 22734 +// gas irOptimized: 22660 // gas legacy: 23190 // gas legacyOptimized: 22508 // roundtrip(string): 0x20, 11, "hello world" -> 0x20, 11, "hello world" -// gas irOptimized: 23513 +// gas irOptimized: 23408 // gas legacy: 23820 // gas legacyOptimized: 23123 // utf8len(string): 0x20, 16, "\xf0\x9f\x98\x83\xf0\x9f\x98\x83\xf0\x9f\x98\x83\xf0\x9f\x98\x83" -> 4 # Input: "😃😃😃😃" # -// gas irOptimized: 24266 +// gas irOptimized: 24026 // gas legacy: 25716 // gas legacyOptimized: 24115 // multiconcat(string,uint256): 0x40, 3, 11, "hello world" -> 0x20, 0x58, 0x68656c6c6f20776f726c6468656c6c6f20776f726c6468656c6c6f20776f726c, 0x6468656c6c6f20776f726c6468656c6c6f20776f726c6468656c6c6f20776f72, 49027192869463622675296414541903001712009715982962058146354235762728281047040 # concatenating 3 times # -// gas irOptimized: 28958 +// gas irOptimized: 28440 // gas legacy: 31621 // gas legacyOptimized: 27914 // benchmark(string,bytes32): 0x40, 0x0842021, 8, "solidity" -> 0x2020 -// gas irOptimized: 2235661 +// gas irOptimized: 2040067 // gas legacy: 4381235 // gas legacyOptimized: 2317529 diff --git a/test/libsolidity/semanticTests/functionCall/failed_create.sol b/test/libsolidity/semanticTests/functionCall/failed_create.sol index b4e7efbb5..b50890f55 100644 --- a/test/libsolidity/semanticTests/functionCall/failed_create.sol +++ b/test/libsolidity/semanticTests/functionCall/failed_create.sol @@ -18,7 +18,7 @@ contract C { // compileViaYul: also // ---- // constructor(), 20 wei -// gas irOptimized: 219233 +// gas irOptimized: 220113 // gas legacy: 288299 // gas legacyOptimized: 177933 // f(uint256): 20 -> 1370859564726510389319704988634906228201275401179 @@ -26,7 +26,7 @@ contract C { // f(uint256): 20 -> FAILURE // x() -> 1 // stack(uint256): 1023 -> FAILURE -// gas irOptimized: 349023 +// gas irOptimized: 345821 // gas legacy: 535367 // gas legacyOptimized: 354656 // x() -> 1 diff --git a/test/libsolidity/semanticTests/functionCall/mapping_array_internal_argument.sol b/test/libsolidity/semanticTests/functionCall/mapping_array_internal_argument.sol index 5d4f25a39..f01a590eb 100644 --- a/test/libsolidity/semanticTests/functionCall/mapping_array_internal_argument.sol +++ b/test/libsolidity/semanticTests/functionCall/mapping_array_internal_argument.sol @@ -20,7 +20,7 @@ contract test { // compileViaYul: also // ---- // set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0 -// gas irOptimized: 112020 +// gas irOptimized: 111965 // gas legacy: 113806 // gas legacyOptimized: 111781 // get(uint8): 1 -> 21, 22, 42, 43 diff --git a/test/libsolidity/semanticTests/functionTypes/store_function.sol b/test/libsolidity/semanticTests/functionTypes/store_function.sol index ddebc11b7..c2678a91d 100644 --- a/test/libsolidity/semanticTests/functionTypes/store_function.sol +++ b/test/libsolidity/semanticTests/functionTypes/store_function.sol @@ -28,6 +28,6 @@ contract C { // compileViaYul: also // ---- // t() -> 9 -// gas irOptimized: 99010 +// gas irOptimized: 99186 // gas legacy: 159083 // gas legacyOptimized: 108916 diff --git a/test/libsolidity/semanticTests/immutable/multi_creation.sol b/test/libsolidity/semanticTests/immutable/multi_creation.sol index a18306984..cd5992ce6 100644 --- a/test/libsolidity/semanticTests/immutable/multi_creation.sol +++ b/test/libsolidity/semanticTests/immutable/multi_creation.sol @@ -29,7 +29,7 @@ contract C { // compileViaYul: also // ---- // f() -> 3, 7, 5 -// gas irOptimized: 127613 +// gas irOptimized: 127592 // gas legacy: 151590 // gas legacyOptimized: 125422 // x() -> 7 diff --git a/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol b/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol index 651ac994e..0dc9845f4 100644 --- a/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol +++ b/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol @@ -23,8 +23,8 @@ contract D { // compileViaYul: also // ---- // f() -> 1 -// gas irOptimized: 78722 +// gas irOptimized: 77164 // gas legacy: 115012 // g() -> 5 -// gas irOptimized: 78811 +// gas irOptimized: 77231 // gas legacy: 115558 diff --git a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol index 85b1fca3b..e012accaf 100644 --- a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol +++ b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol @@ -25,5 +25,5 @@ contract B { // compileViaYul: also // ---- // g() -> 42 -// gas irOptimized: 84629 +// gas irOptimized: 80945 // gas legacy: 125609 diff --git a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol index b4f03446c..4105577f0 100644 --- a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol +++ b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol @@ -25,6 +25,6 @@ contract B { // compileViaYul: also // ---- // g() -> 42 -// gas irOptimized: 105784 +// gas irOptimized: 111913 // gas legacy: 185181 // gas legacyOptimized: 114726 diff --git a/test/libsolidity/semanticTests/inlineAssembly/keccak_yul_optimization.sol b/test/libsolidity/semanticTests/inlineAssembly/keccak_yul_optimization.sol index 88ead1eb3..85a93b3dc 100644 --- a/test/libsolidity/semanticTests/inlineAssembly/keccak_yul_optimization.sol +++ b/test/libsolidity/semanticTests/inlineAssembly/keccak_yul_optimization.sol @@ -26,10 +26,10 @@ contract C { // compileViaYul: also // ---- // f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80 -// gas irOptimized: 22306 +// gas irOptimized: 22239 // gas legacy: 23385 // gas legacyOptimized: 23092 // g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80 -// gas irOptimized: 21287 +// gas irOptimized: 21277 // gas legacy: 21462 // gas legacyOptimized: 21256 diff --git a/test/libsolidity/semanticTests/interface_inheritance_conversions.sol b/test/libsolidity/semanticTests/interface_inheritance_conversions.sol index 70f52d4c6..11cb93832 100644 --- a/test/libsolidity/semanticTests/interface_inheritance_conversions.sol +++ b/test/libsolidity/semanticTests/interface_inheritance_conversions.sol @@ -37,10 +37,10 @@ contract C { // compileViaYul: also // ---- // convertParent() -> 1 -// gas irOptimized: 87655 +// gas irOptimized: 85640 // convertSubA() -> 1, 2 -// gas irOptimized: 88451 +// gas irOptimized: 86395 // gas legacy: 99303 // convertSubB() -> 1, 3 -// gas irOptimized: 88385 +// gas irOptimized: 86338 // gas legacy: 99237 diff --git a/test/libsolidity/semanticTests/salted_create/salted_create.sol b/test/libsolidity/semanticTests/salted_create/salted_create.sol index 064159de3..5374d2352 100644 --- a/test/libsolidity/semanticTests/salted_create/salted_create.sol +++ b/test/libsolidity/semanticTests/salted_create/salted_create.sol @@ -22,6 +22,6 @@ contract A { // ---- // different_salt() -> true // same_salt() -> true -// gas irOptimized: 98438948 +// gas irOptimized: 98438914 // gas legacy: 98439116 // gas legacyOptimized: 98438970 diff --git a/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol b/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol index 2e386ee45..17edaf3eb 100644 --- a/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol +++ b/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol @@ -22,6 +22,6 @@ contract A { // compileViaYul: also // ---- // f(), 10 ether -> 3007, 3008, 3009 -// gas irOptimized: 270255 +// gas irOptimized: 273275 // gas legacy: 422885 // gas legacyOptimized: 287856 diff --git a/test/libsolidity/semanticTests/storage/packed_storage_structs_bytes.sol b/test/libsolidity/semanticTests/storage/packed_storage_structs_bytes.sol index 2fdff6c56..caa385887 100644 --- a/test/libsolidity/semanticTests/storage/packed_storage_structs_bytes.sol +++ b/test/libsolidity/semanticTests/storage/packed_storage_structs_bytes.sol @@ -46,6 +46,6 @@ contract C { // compileViaYul: also // ---- // test() -> true -// gas irOptimized: 135141 +// gas irOptimized: 134587 // gas legacy: 136036 // gas legacyOptimized: 133480 diff --git a/test/libsolidity/semanticTests/structs/calldata/calldata_struct_with_nested_array_to_storage.sol b/test/libsolidity/semanticTests/structs/calldata/calldata_struct_with_nested_array_to_storage.sol index 3587d8e17..7b84033d8 100644 --- a/test/libsolidity/semanticTests/structs/calldata/calldata_struct_with_nested_array_to_storage.sol +++ b/test/libsolidity/semanticTests/structs/calldata/calldata_struct_with_nested_array_to_storage.sol @@ -18,6 +18,6 @@ contract C { // compileViaYul: also // ---- // f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 77, 1, 2, 88 -// gas irOptimized: 203716 +// gas irOptimized: 203397 // gas legacy: 209194 // gas legacyOptimized: 203583 diff --git a/test/libsolidity/semanticTests/structs/conversion/recursive_storage_memory.sol b/test/libsolidity/semanticTests/structs/conversion/recursive_storage_memory.sol index 93b63ff5c..0d0aba8c8 100644 --- a/test/libsolidity/semanticTests/structs/conversion/recursive_storage_memory.sol +++ b/test/libsolidity/semanticTests/structs/conversion/recursive_storage_memory.sol @@ -25,6 +25,6 @@ contract CopyTest { // compileViaYul: also // ---- // run() -> 2, 23, 42 -// gas irOptimized: 195077 +// gas irOptimized: 193980 // gas legacy: 186016 // gas legacyOptimized: 184668 diff --git a/test/libsolidity/semanticTests/structs/memory_structs_nested_load.sol b/test/libsolidity/semanticTests/structs/memory_structs_nested_load.sol index f48c54807..12ec4ca18 100644 --- a/test/libsolidity/semanticTests/structs/memory_structs_nested_load.sol +++ b/test/libsolidity/semanticTests/structs/memory_structs_nested_load.sol @@ -69,7 +69,7 @@ contract Test { // compileViaYul: also // ---- // load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 -// gas irOptimized: 111174 +// gas irOptimized: 111179 // gas legacy: 112999 // gas legacyOptimized: 110881 // store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 diff --git a/test/libsolidity/semanticTests/structs/struct_containing_bytes_copy_and_delete.sol b/test/libsolidity/semanticTests/structs/struct_containing_bytes_copy_and_delete.sol index 070fcf920..a677b5be8 100644 --- a/test/libsolidity/semanticTests/structs/struct_containing_bytes_copy_and_delete.sol +++ b/test/libsolidity/semanticTests/structs/struct_containing_bytes_copy_and_delete.sol @@ -25,7 +25,7 @@ contract c { // ---- // storageEmpty -> 1 // set(uint256,bytes,uint256): 12, 0x60, 13, 33, "12345678901234567890123456789012", "3" -> true -// gas irOptimized: 133819 +// gas irOptimized: 133752 // gas legacy: 134436 // gas legacyOptimized: 133879 // test(uint256): 32 -> "3" diff --git a/test/libsolidity/semanticTests/structs/struct_copy.sol b/test/libsolidity/semanticTests/structs/struct_copy.sol index ccaaeaa52..0bbb6489e 100644 --- a/test/libsolidity/semanticTests/structs/struct_copy.sol +++ b/test/libsolidity/semanticTests/structs/struct_copy.sol @@ -38,12 +38,12 @@ contract c { // compileViaYul: also // ---- // set(uint256): 7 -> true -// gas irOptimized: 109985 +// gas irOptimized: 110011 // gas legacy: 110616 // gas legacyOptimized: 110006 // retrieve(uint256): 7 -> 1, 3, 4, 2 // copy(uint256,uint256): 7, 8 -> true -// gas irOptimized: 118701 +// gas irOptimized: 118707 // gas legacy: 119166 // gas legacyOptimized: 118622 // retrieve(uint256): 7 -> 1, 3, 4, 2 diff --git a/test/libsolidity/semanticTests/structs/struct_copy_via_local.sol b/test/libsolidity/semanticTests/structs/struct_copy_via_local.sol index 441584a5e..21757ea40 100644 --- a/test/libsolidity/semanticTests/structs/struct_copy_via_local.sol +++ b/test/libsolidity/semanticTests/structs/struct_copy_via_local.sol @@ -21,6 +21,6 @@ contract c { // compileViaYul: also // ---- // test() -> true -// gas irOptimized: 110144 +// gas irOptimized: 110186 // gas legacy: 110627 // gas legacyOptimized: 109706 diff --git a/test/libsolidity/semanticTests/structs/struct_delete_storage_nested_small.sol b/test/libsolidity/semanticTests/structs/struct_delete_storage_nested_small.sol index 838539628..bc18d3192 100644 --- a/test/libsolidity/semanticTests/structs/struct_delete_storage_nested_small.sol +++ b/test/libsolidity/semanticTests/structs/struct_delete_storage_nested_small.sol @@ -33,4 +33,4 @@ contract C { // compileViaYul: true // ---- // f() -> 0, 0, 0 -// gas irOptimized: 117388 +// gas irOptimized: 117289 diff --git a/test/libsolidity/semanticTests/structs/struct_delete_storage_with_array.sol b/test/libsolidity/semanticTests/structs/struct_delete_storage_with_array.sol index 14e170a4c..e759520b4 100644 --- a/test/libsolidity/semanticTests/structs/struct_delete_storage_with_array.sol +++ b/test/libsolidity/semanticTests/structs/struct_delete_storage_with_array.sol @@ -44,7 +44,7 @@ contract C { // compileViaYul: also // ---- // f() -> -// gas irOptimized: 121704 +// gas irOptimized: 121618 // gas legacy: 122132 // gas legacyOptimized: 121500 // g() -> diff --git a/test/libsolidity/semanticTests/structs/struct_delete_storage_with_arrays_small.sol b/test/libsolidity/semanticTests/structs/struct_delete_storage_with_arrays_small.sol index 6425c0d37..6f88df394 100644 --- a/test/libsolidity/semanticTests/structs/struct_delete_storage_with_arrays_small.sol +++ b/test/libsolidity/semanticTests/structs/struct_delete_storage_with_arrays_small.sol @@ -27,4 +27,4 @@ contract C { // compileViaYul: true // ---- // f() -> 0 -// gas irOptimized: 112160 +// gas irOptimized: 111896 diff --git a/test/libsolidity/semanticTests/structs/struct_memory_to_storage_function_ptr.sol b/test/libsolidity/semanticTests/structs/struct_memory_to_storage_function_ptr.sol index caa2b693f..fe791a68d 100644 --- a/test/libsolidity/semanticTests/structs/struct_memory_to_storage_function_ptr.sol +++ b/test/libsolidity/semanticTests/structs/struct_memory_to_storage_function_ptr.sol @@ -32,6 +32,6 @@ contract C { // compileViaYul: also // ---- // f() -> 42, 23, 34, 42, 42 -// gas irOptimized: 110592 +// gas irOptimized: 110966 // gas legacy: 112021 // gas legacyOptimized: 110548 diff --git a/test/libsolidity/semanticTests/structs/structs.sol b/test/libsolidity/semanticTests/structs/structs.sol index 46b596e39..b56a2ec22 100644 --- a/test/libsolidity/semanticTests/structs/structs.sol +++ b/test/libsolidity/semanticTests/structs/structs.sol @@ -32,7 +32,7 @@ contract test { // ---- // check() -> false // set() -> -// gas irOptimized: 134389 +// gas irOptimized: 134335 // gas legacy: 135277 // gas legacyOptimized: 134064 // check() -> true diff --git a/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol b/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol index 3596d2c99..1927b2519 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol @@ -51,11 +51,11 @@ contract C { // compileViaYul: also // ---- // test_f() -> true -// gas irOptimized: 122887 +// gas irOptimized: 122509 // gas legacy: 126168 // gas legacyOptimized: 123199 // test_g() -> true -// gas irOptimized: 96673 +// gas irOptimized: 95980 // gas legacy: 101311 // gas legacyOptimized: 96566 // addresses(uint256): 0 -> 0x18 diff --git a/test/libsolidity/semanticTests/userDefinedValueType/calldata_to_storage.sol b/test/libsolidity/semanticTests/userDefinedValueType/calldata_to_storage.sol index 9827d6cd1..433d1969c 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/calldata_to_storage.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/calldata_to_storage.sol @@ -25,18 +25,18 @@ contract C { // ---- // s() -> 0, 0, 0x00, 0 // f((uint8,uint16,bytes2,uint8)): 1, 0xff, "ab", 15 -> -// gas irOptimized: 44860 +// gas irOptimized: 44786 // gas legacy: 47200 // gas legacyOptimized: 44923 // s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15 // g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3 -// gas irOptimized: 69306 +// gas irOptimized: 69097 // gas legacy: 75466 // gas legacyOptimized: 74255 // small(uint256): 0 -> 1 // small(uint256): 1 -> 2 // h(bytes2[]): 0x20, 3, "ab", "cd", "ef" -> 0x20, 3, "ab", "cd", "ef" -// gas irOptimized: 69510 +// gas irOptimized: 69174 // gas legacy: 75156 // gas legacyOptimized: 74342 // l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol b/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol index 155a4bd87..4db14ff73 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol @@ -115,33 +115,33 @@ contract ERC20 { // ---- // constructor() // ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14 -// gas irOptimized: 462361 +// gas irOptimized: 442239 // gas legacy: 861547 // gas legacyOptimized: 420959 // totalSupply() -> 20 -// gas irOptimized: 23378 +// gas irOptimized: 23415 // gas legacy: 23653 // gas legacyOptimized: 23368 // transfer(address,uint256): 2, 5 -> true // ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05 -// gas irOptimized: 48503 +// gas irOptimized: 48471 // gas legacy: 49572 // gas legacyOptimized: 48575 // decreaseAllowance(address,uint256): 2, 0 -> true // ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00 -// gas irOptimized: 26327 +// gas irOptimized: 26275 // gas legacy: 27204 // gas legacyOptimized: 26317 // decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex"4e487b71", 0x11 -// gas irOptimized: 24040 +// gas irOptimized: 24042 // gas legacy: 24506 // gas legacyOptimized: 24077 // transfer(address,uint256): 2, 14 -> true // ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e -// gas irOptimized: 28603 +// gas irOptimized: 28571 // gas legacy: 29672 // gas legacyOptimized: 28675 // transfer(address,uint256): 2, 2 -> FAILURE, hex"4e487b71", 0x11 -// gas irOptimized: 24052 +// gas irOptimized: 24071 // gas legacy: 24492 // gas legacyOptimized: 24074 diff --git a/test/libsolidity/semanticTests/userDefinedValueType/memory_to_storage.sol b/test/libsolidity/semanticTests/userDefinedValueType/memory_to_storage.sol index e1a7c1c5b..04e993682 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/memory_to_storage.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/memory_to_storage.sol @@ -25,18 +25,18 @@ contract C { // ---- // s() -> 0, 0, 0x00, 0 // f((uint8,uint16,bytes2,uint8)): 1, 0xff, "ab", 15 -> -// gas irOptimized: 44551 +// gas irOptimized: 44536 // gas legacy: 46213 // gas legacyOptimized: 44671 // s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15 // g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3 -// gas irOptimized: 69671 +// gas irOptimized: 69555 // gas legacy: 76557 // gas legacyOptimized: 74834 // small(uint256): 0 -> 1 // small(uint256): 1 -> 2 // h(bytes2[]): 0x20, 3, "ab", "cd", "ef" -> 0x20, 3, "ab", "cd", "ef" -// gas irOptimized: 69928 +// gas irOptimized: 69617 // gas legacy: 76238 // gas legacyOptimized: 74921 // l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/semanticTests/userDefinedValueType/zero_cost_abstraction_comparison_elementary.sol b/test/libsolidity/semanticTests/userDefinedValueType/zero_cost_abstraction_comparison_elementary.sol index d7b9db30b..d2d46c708 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/zero_cost_abstraction_comparison_elementary.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/zero_cost_abstraction_comparison_elementary.sol @@ -20,18 +20,18 @@ contract C { // compileViaYul: also // ---- // getX() -> 0 -// gas irOptimized: 23353 +// gas irOptimized: 23379 // gas legacy: 23479 // gas legacyOptimized: 23311 // setX(int256): 5 -> -// gas irOptimized: 43511 +// gas irOptimized: 43510 // gas legacy: 43724 // gas legacyOptimized: 43516 // getX() -> 5 -// gas irOptimized: 23353 +// gas irOptimized: 23379 // gas legacy: 23479 // gas legacyOptimized: 23311 // add(int256,int256): 200, 99 -> 299 -// gas irOptimized: 21794 +// gas irOptimized: 21764 // gas legacy: 22394 // gas legacyOptimized: 21813 diff --git a/test/libsolidity/semanticTests/userDefinedValueType/zero_cost_abstraction_comparison_userdefined.sol b/test/libsolidity/semanticTests/userDefinedValueType/zero_cost_abstraction_comparison_userdefined.sol index 29038a861..44d87c397 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/zero_cost_abstraction_comparison_userdefined.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/zero_cost_abstraction_comparison_userdefined.sol @@ -21,18 +21,18 @@ contract C { // compileViaYul: also // ---- // getX() -> 0 -// gas irOptimized: 23353 +// gas irOptimized: 23379 // gas legacy: 23608 // gas legacyOptimized: 23311 // setX(int256): 5 -> -// gas irOptimized: 43511 +// gas irOptimized: 43510 // gas legacy: 43724 // gas legacyOptimized: 43516 // getX() -> 5 -// gas irOptimized: 23353 +// gas irOptimized: 23379 // gas legacy: 23608 // gas legacyOptimized: 23311 // add(int256,int256): 200, 99 -> 299 -// gas irOptimized: 21794 +// gas irOptimized: 21764 // gas legacy: 22523 // gas legacyOptimized: 21813 diff --git a/test/libsolidity/semanticTests/various/destructuring_assignment.sol b/test/libsolidity/semanticTests/various/destructuring_assignment.sol index b8a314d32..ee6f7690d 100644 --- a/test/libsolidity/semanticTests/various/destructuring_assignment.sol +++ b/test/libsolidity/semanticTests/various/destructuring_assignment.sol @@ -36,6 +36,6 @@ contract C { // compileViaYul: also // ---- // f(bytes): 0x20, 0x5, "abcde" -> 0 -// gas irOptimized: 240334 +// gas irOptimized: 240685 // gas legacy: 240358 // gas legacyOptimized: 239682 diff --git a/test/libsolidity/semanticTests/various/erc20.sol b/test/libsolidity/semanticTests/various/erc20.sol index 6e7487ee5..204e620d6 100644 --- a/test/libsolidity/semanticTests/various/erc20.sol +++ b/test/libsolidity/semanticTests/various/erc20.sol @@ -98,33 +98,33 @@ contract ERC20 { // ---- // constructor() // ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14 -// gas irOptimized: 459547 +// gas irOptimized: 437697 // gas legacy: 833310 // gas legacyOptimized: 416135 // totalSupply() -> 20 -// gas irOptimized: 23378 +// gas irOptimized: 23415 // gas legacy: 23524 // gas legacyOptimized: 23368 // transfer(address,uint256): 2, 5 -> true // ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05 -// gas irOptimized: 48503 +// gas irOptimized: 48471 // gas legacy: 49317 // gas legacyOptimized: 48491 // decreaseAllowance(address,uint256): 2, 0 -> true // ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00 -// gas irOptimized: 26327 +// gas irOptimized: 26275 // gas legacy: 27012 // gas legacyOptimized: 26275 // decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex"4e487b71", 0x11 -// gas irOptimized: 24040 +// gas irOptimized: 24042 // gas legacy: 24467 // gas legacyOptimized: 24056 // transfer(address,uint256): 2, 14 -> true // ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e -// gas irOptimized: 28603 +// gas irOptimized: 28571 // gas legacy: 29417 // gas legacyOptimized: 28591 // transfer(address,uint256): 2, 2 -> FAILURE, hex"4e487b71", 0x11 -// gas irOptimized: 24052 +// gas irOptimized: 24071 // gas legacy: 24453 // gas legacyOptimized: 24053 diff --git a/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol b/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol index a8e9ce1ed..8ef472136 100644 --- a/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol +++ b/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol @@ -22,6 +22,6 @@ contract C { // compileViaYul: also // ---- // g() -> 2, 6 -// gas irOptimized: 178952 +// gas irOptimized: 178953 // gas legacy: 180890 // gas legacyOptimized: 179609 diff --git a/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol b/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol index 33afcb66f..ab6d6e59a 100644 --- a/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol +++ b/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol @@ -38,10 +38,10 @@ contract D { // f() -> 0x1 # This should work, next should throw # // gas legacy: 103844 // fview() -> FAILURE -// gas irOptimized: 98438630 +// gas irOptimized: 98438627 // gas legacy: 98438803 // gas legacyOptimized: 98438596 // fpure() -> FAILURE -// gas irOptimized: 98438630 +// gas irOptimized: 98438627 // gas legacy: 98438803 // gas legacyOptimized: 98438597 diff --git a/test/libsolidity/semanticTests/various/swap_in_storage_overwrite.sol b/test/libsolidity/semanticTests/various/swap_in_storage_overwrite.sol index 12e491968..c8398b2bf 100644 --- a/test/libsolidity/semanticTests/various/swap_in_storage_overwrite.sol +++ b/test/libsolidity/semanticTests/various/swap_in_storage_overwrite.sol @@ -30,7 +30,7 @@ contract c { // x() -> 0, 0 // y() -> 0, 0 // set() -> -// gas irOptimized: 109734 +// gas irOptimized: 109733 // gas legacy: 109732 // gas legacyOptimized: 109682 // x() -> 1, 2 diff --git a/test/libsolidity/semanticTests/viaYul/array_memory_index_access.sol b/test/libsolidity/semanticTests/viaYul/array_memory_index_access.sol index 83aefbc61..b603fb786 100644 --- a/test/libsolidity/semanticTests/viaYul/array_memory_index_access.sol +++ b/test/libsolidity/semanticTests/viaYul/array_memory_index_access.sol @@ -28,7 +28,7 @@ contract C { // index(uint256): 10 -> true // index(uint256): 20 -> true // index(uint256): 0xFF -> true -// gas irOptimized: 151952 +// gas irOptimized: 138441 // gas legacy: 248854 // gas legacyOptimized: 152638 // accessIndex(uint256,int256): 10, 1 -> 2 diff --git a/test/libsolidity/semanticTests/viaYul/array_storage_index_access.sol b/test/libsolidity/semanticTests/viaYul/array_storage_index_access.sol index 5241f29c0..24d0e9f14 100644 --- a/test/libsolidity/semanticTests/viaYul/array_storage_index_access.sol +++ b/test/libsolidity/semanticTests/viaYul/array_storage_index_access.sol @@ -18,33 +18,33 @@ contract C { // ---- // test_indices(uint256): 1 -> // test_indices(uint256): 129 -> -// gas irOptimized: 3041780 +// gas irOptimized: 3032986 // gas legacy: 3071205 // gas legacyOptimized: 3011873 // test_indices(uint256): 5 -> -// gas irOptimized: 368208 +// gas irOptimized: 367642 // gas legacy: 369241 // gas legacyOptimized: 366149 // test_indices(uint256): 10 -> // test_indices(uint256): 15 -> -// gas irOptimized: 73803 +// gas irOptimized: 72860 // test_indices(uint256): 0xFF -> -// gas irOptimized: 3455818 +// gas irOptimized: 3438610 // gas legacy: 3514167 // gas legacyOptimized: 3398107 // test_indices(uint256): 1000 -> -// gas irOptimized: 18383600 +// gas irOptimized: 18318372 // gas legacy: 18617999 // gas legacyOptimized: 18178944 // test_indices(uint256): 129 -> -// gas irOptimized: 2742698 +// gas irOptimized: 2733570 // gas legacy: 2772735 // gas legacyOptimized: 2716547 // test_indices(uint256): 128 -> -// gas irOptimized: 434013 +// gas irOptimized: 426682 // gas legacy: 467272 // gas legacyOptimized: 418424 // test_indices(uint256): 1 -> -// gas irOptimized: 363418 +// gas irOptimized: 363074 // gas legacy: 363407 // gas legacyOptimized: 361811 diff --git a/test/libsolidity/semanticTests/viaYul/array_storage_index_boundary_test.sol b/test/libsolidity/semanticTests/viaYul/array_storage_index_boundary_test.sol index 4b377ec2d..975130c51 100644 --- a/test/libsolidity/semanticTests/viaYul/array_storage_index_boundary_test.sol +++ b/test/libsolidity/semanticTests/viaYul/array_storage_index_boundary_test.sol @@ -18,11 +18,11 @@ contract C { // test_boundary_check(uint256,uint256): 1, 1 -> FAILURE, hex"4e487b71", 0x32 // test_boundary_check(uint256,uint256): 10, 10 -> FAILURE, hex"4e487b71", 0x32 // test_boundary_check(uint256,uint256): 256, 256 -> FAILURE, hex"4e487b71", 0x32 -// gas irOptimized: 139319 +// gas irOptimized: 137849 // gas legacy: 131830 // gas legacyOptimized: 112054 // test_boundary_check(uint256,uint256): 256, 255 -> 0 -// gas irOptimized: 141481 +// gas irOptimized: 140028 // gas legacy: 134149 // gas legacyOptimized: 114233 // test_boundary_check(uint256,uint256): 256, 0xFFFF -> FAILURE, hex"4e487b71", 0x32 diff --git a/test/libsolidity/semanticTests/viaYul/array_storage_index_zeroed_test.sol b/test/libsolidity/semanticTests/viaYul/array_storage_index_zeroed_test.sol index 870f339fc..b2e0cb546 100644 --- a/test/libsolidity/semanticTests/viaYul/array_storage_index_zeroed_test.sol +++ b/test/libsolidity/semanticTests/viaYul/array_storage_index_zeroed_test.sol @@ -54,18 +54,18 @@ contract C { // ---- // test_zeroed_indicies(uint256): 1 -> // test_zeroed_indicies(uint256): 5 -> -// gas irOptimized: 131736 +// gas irOptimized: 131197 // gas legacy: 132367 // gas legacyOptimized: 129586 // test_zeroed_indicies(uint256): 10 -> -// gas irOptimized: 175795 +// gas irOptimized: 174805 // gas legacy: 177329 // gas legacyOptimized: 172224 // test_zeroed_indicies(uint256): 15 -> -// gas irOptimized: 199485 +// gas irOptimized: 198055 // gas legacy: 201954 // gas legacyOptimized: 194604 // test_zeroed_indicies(uint256): 0xFF -> -// gas irOptimized: 6123320 +// gas irOptimized: 6098185 // gas legacy: 6163149 // gas legacyOptimized: 6029474 diff --git a/test/libsolidity/semanticTests/viaYul/array_storage_length_access.sol b/test/libsolidity/semanticTests/viaYul/array_storage_length_access.sol index 47b75c08e..c5af58449 100644 --- a/test/libsolidity/semanticTests/viaYul/array_storage_length_access.sol +++ b/test/libsolidity/semanticTests/viaYul/array_storage_length_access.sol @@ -14,11 +14,11 @@ contract C { // set_get_length(uint256): 10 -> 10 // set_get_length(uint256): 20 -> 20 // set_get_length(uint256): 0xFF -> 0xFF -// gas irOptimized: 96934 +// gas irOptimized: 96690 // gas legacy: 126722 // gas legacyOptimized: 107818 // set_get_length(uint256): 0xFFF -> 0xFFF -// gas irOptimized: 1221706 +// gas irOptimized: 1217857 // gas legacy: 1702119 // gas legacyOptimized: 1398420 // set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas # diff --git a/test/libsolidity/semanticTests/viaYul/array_storage_push_empty.sol b/test/libsolidity/semanticTests/viaYul/array_storage_push_empty.sol index 05970805f..5c7c4cba8 100644 --- a/test/libsolidity/semanticTests/viaYul/array_storage_push_empty.sol +++ b/test/libsolidity/semanticTests/viaYul/array_storage_push_empty.sol @@ -13,11 +13,11 @@ contract C { // compileViaYul: also // ---- // pushEmpty(uint256): 128 -// gas irOptimized: 414881 +// gas irOptimized: 412570 // gas legacy: 417287 // gas legacyOptimized: 399048 // pushEmpty(uint256): 256 -// gas irOptimized: 706405 +// gas irOptimized: 702558 // gas legacy: 715083 // gas legacyOptimized: 688908 // pushEmpty(uint256): 38869 -> FAILURE # out-of-gas # diff --git a/test/libsolidity/semanticTests/viaYul/array_storage_push_empty_length_address.sol b/test/libsolidity/semanticTests/viaYul/array_storage_push_empty_length_address.sol index 06e00f6db..5e5d1c962 100644 --- a/test/libsolidity/semanticTests/viaYul/array_storage_push_empty_length_address.sol +++ b/test/libsolidity/semanticTests/viaYul/array_storage_push_empty_length_address.sol @@ -18,15 +18,15 @@ contract C { // set_get_length(uint256): 10 -> 10 // set_get_length(uint256): 20 -> 20 // set_get_length(uint256): 0 -> 0 -// gas irOptimized: 77961 +// gas irOptimized: 77628 // gas legacy: 77730 // gas legacyOptimized: 77162 // set_get_length(uint256): 0xFF -> 0xFF -// gas irOptimized: 143348 +// gas irOptimized: 141805 // gas legacy: 678237 // gas legacyOptimized: 115104 // set_get_length(uint256): 0xFFF -> 0xFFF -// gas irOptimized: 1824725 +// gas irOptimized: 1801672 // gas legacy: 9873774 // gas legacyOptimized: 1398546 // set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas # diff --git a/test/libsolidity/semanticTests/viaYul/array_storage_push_pop.sol b/test/libsolidity/semanticTests/viaYul/array_storage_push_pop.sol index 7cc1f9e54..e802e3687 100644 --- a/test/libsolidity/semanticTests/viaYul/array_storage_push_pop.sol +++ b/test/libsolidity/semanticTests/viaYul/array_storage_push_pop.sol @@ -15,15 +15,15 @@ contract C { // set_get_length(uint256): 1 -> 0 // set_get_length(uint256): 10 -> 0 // set_get_length(uint256): 20 -> 0 -// gas irOptimized: 86888 +// gas irOptimized: 86331 // gas legacy: 85822 // gas legacyOptimized: 83608 // set_get_length(uint256): 0xFF -> 0 -// gas irOptimized: 828783 +// gas irOptimized: 821881 // gas legacy: 810327 // gas legacyOptimized: 786258 // set_get_length(uint256): 0xFFF -> 0 -// gas irOptimized: 12951675 +// gas irOptimized: 12841093 // gas legacy: 12649059 // gas legacyOptimized: 12267870 // set_get_length(uint256): 0xFFFF -> FAILURE # Out-of-gas # diff --git a/test/libyul/EVMCodeTransformTest.cpp b/test/libyul/EVMCodeTransformTest.cpp index 38ef5ad39..8986acc1b 100644 --- a/test/libyul/EVMCodeTransformTest.cpp +++ b/test/libyul/EVMCodeTransformTest.cpp @@ -20,6 +20,10 @@ #include #include +#include +#include + +#include #include @@ -61,7 +65,18 @@ TestCase::TestResult EVMCodeTransformTest::run(ostream& _stream, string const& _ return TestResult::FatalError; } - m_obtainedResult = evmasm::disassemble(stack.assemble(AssemblyStack::Machine::EVM).bytecode->bytecode, "\n"); + evmasm::Assembly assembly; + EthAssemblyAdapter adapter(assembly); + EVMObjectCompiler::compile( + *stack.parserResult(), + adapter, + EVMDialect::strictAssemblyForEVMObjects(EVMVersion{}), + m_stackOpt + ); + + std::ostringstream output; + output << assembly; + m_obtainedResult = output.str(); return checkResult(_stream, _linePrefix, _formatted); } diff --git a/test/libyul/evmCodeTransform/early_push_on_deep_swap.yul b/test/libyul/evmCodeTransform/early_push_on_deep_swap.yul new file mode 100644 index 000000000..5e119cc73 --- /dev/null +++ b/test/libyul/evmCodeTransform/early_push_on_deep_swap.yul @@ -0,0 +1,54 @@ +{ + extcodecopy(div(div(call(call(gas(),0x10000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000, 0x1000000000000000000000000000000000000000000000000000, 0x10000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000, 0x1000000000000000000000000000000000000000000000000000000), 0x10000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x1000000000000000000000000000000000000000000000000000000000, 0x10000000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000000, 0x1000000000000000000000000000000000000000000000000000000000000),0x10000000000000000000000000000000000000000000000000000000000000),0x100000000000000000000000000000000000000000000000000000000000000), 0x1000000000000000000000000000000000000000000000000000000000000000, 0x1000000000000000000000000000000000000000000000000000000000000001, 0x100000000000000000000000000000000000000000000000000000000000001) +} +// ==== +// stackOptimization: true +// ---- +// /* "":1027:1092 */ +// 0x0100000000000000000000000000000000000000000000000000000000000001 +// /* "":959:1025 */ +// 0x1000000000000000000000000000000000000000000000000000000000000001 +// /* "":891:957 */ +// 0x1000000000000000000000000000000000000000000000000000000000000000 +// /* "":823:888 */ +// 0x0100000000000000000000000000000000000000000000000000000000000000 +// /* "":757:821 */ +// 0x10000000000000000000000000000000000000000000000000000000000000 +// /* "":692:755 */ +// 0x01000000000000000000000000000000000000000000000000000000000000 +// /* "":628:690 */ +// 0x100000000000000000000000000000000000000000000000000000000000 +// /* "":565:626 */ +// 0x010000000000000000000000000000000000000000000000000000000000 +// /* "":503:563 */ +// 0x1000000000000000000000000000000000000000000000000000000000 +// /* "":442:501 */ +// 0x0100000000000000000000000000000000000000000000000000000000 +// /* "":382:440 */ +// 0x10000000000000000000000000000000000000000000000000000000 +// /* "":322:379 */ +// 0x01000000000000000000000000000000000000000000000000000000 +// /* "":264:320 */ +// 0x100000000000000000000000000000000000000000000000000000 +// /* "":207:262 */ +// 0x010000000000000000000000000000000000000000000000000000 +// /* "":151:205 */ +// 0x1000000000000000000000000000000000000000000000000000 +// /* "":96:149 */ +// 0x0100000000000000000000000000000000000000000000000000 +// /* "":42:94 */ +// 0x10000000000000000000000000000000000000000000000000 +// /* "":36:41 */ +// gas +// /* "":31:380 */ +// call +// /* "":26:756 */ +// call +// /* "":22:822 */ +// div +// /* "":18:889 */ +// div +// /* "":6:1093 */ +// extcodecopy +// /* "":0:1095 */ +// stop diff --git a/test/libyul/evmCodeTransform/literal_loop.yul b/test/libyul/evmCodeTransform/literal_loop.yul new file mode 100644 index 000000000..d743836cb --- /dev/null +++ b/test/libyul/evmCodeTransform/literal_loop.yul @@ -0,0 +1,74 @@ +object "main" { + code { + codecopy(0, dataoffset("deployed"), datasize("deployed")) + return(0, datasize("deployed")) + } + object "deployed" { + code { + for {} + add(delegatecall(delegatecall(call(selfbalance(), 0x0, 0x0, 0x0, 0x0, 0x0, 0x0), 0x0, 0x0, 0x0, 0x0, 0x0), 0x0, 0x0, 0x0, 0x0, 0x0),0x0) + {} + {} + } + } +} +// ==== +// stackOptimization: true +// ---- +// /* "":62:82 */ +// dataSize(sub_0) +// /* "":38:60 */ +// dataOffset(sub_0) +// /* "":35:36 */ +// 0x00 +// /* "":26:83 */ +// codecopy +// /* "":96:116 */ +// dataSize(sub_0) +// /* "":93:94 */ +// 0x00 +// /* "":86:117 */ +// return +// stop +// +// sub_0: assembly { +// /* "":164:300 */ +// tag_1: +// /* "":296:299 */ +// 0x00 +// /* "":199:212 */ +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// selfbalance +// /* "":194:243 */ +// call +// /* "":181:269 */ +// delegatecall +// /* "":168:295 */ +// delegatecall +// /* "":164:300 */ +// add +// tag_2 +// jumpi +// /* "":154:312 */ +// tag_3: +// stop +// /* "":310:312 */ +// tag_2: +// /* "":304:306 */ +// jump(tag_1) +// } diff --git a/test/libyul/evmCodeTransform/nonempty_initial_layout.yul b/test/libyul/evmCodeTransform/nonempty_initial_layout.yul new file mode 100644 index 000000000..eb1a787c0 --- /dev/null +++ b/test/libyul/evmCodeTransform/nonempty_initial_layout.yul @@ -0,0 +1,17 @@ +{ + if 0x2000000000000000000000000000000000000000000000000000000000 {} +} +// ==== +// stackOptimization: true +// ---- +// /* "":9:69 */ +// 0x2000000000000000000000000000000000000000000000000000000000 +// /* "":6:72 */ +// tag_1 +// jumpi +// /* "":0:74 */ +// tag_2: +// stop +// /* "":70:72 */ +// tag_1: +// jump(tag_2) diff --git a/test/libyul/evmCodeTransform/stackReuse/for_1.yul b/test/libyul/evmCodeTransform/stackReuse/for_1.yul index e2f4ba128..b02710598 100644 --- a/test/libyul/evmCodeTransform/stackReuse/for_1.yul +++ b/test/libyul/evmCodeTransform/stackReuse/for_1.yul @@ -2,18 +2,15 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x0 -// POP -// JUMPDEST -// PUSH1 0x1 -// ISZERO -// PUSH1 0x11 -// JUMPI -// PUSH1 0x3 -// POP -// JUMPDEST -// PUSH1 0x3 -// JUMP -// JUMPDEST -// PUSH1 0x2 -// POP +// /* "":17:18 */ +// 0x00 +// /* "":6:20 */ +// pop +// /* "":27:41 */ +// tag_1: +// /* "":38:39 */ +// 0x03 +// /* "":27:41 */ +// pop +// /* "":23:26 */ +// jump(tag_1) diff --git a/test/libyul/evmCodeTransform/stackReuse/for_2.yul b/test/libyul/evmCodeTransform/stackReuse/for_2.yul index f1f7460d4..37d372fb9 100644 --- a/test/libyul/evmCodeTransform/stackReuse/for_2.yul +++ b/test/libyul/evmCodeTransform/stackReuse/for_2.yul @@ -2,21 +2,19 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x0 -// JUMPDEST -// PUSH1 0x1 -// ISZERO -// PUSH1 0x14 -// JUMPI -// PUSH1 0x8 -// SWAP1 -// POP -// PUSH1 0x3 -// POP -// JUMPDEST -// PUSH1 0x2 -// JUMP -// JUMPDEST -// POP -// PUSH1 0x2 -// POP +// /* "":17:18 */ +// 0x00 +// /* "":6:20 */ +// pop +// /* "":27:48 */ +// tag_1: +// /* "":34:35 */ +// 0x08 +// /* "":36:46 */ +// pop +// /* "":45:46 */ +// 0x03 +// /* "":27:48 */ +// pop +// /* "":23:26 */ +// jump(tag_1) diff --git a/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse.yul b/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse.yul index 13048c020..96637da89 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse.yul @@ -4,25 +4,23 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x17 -// JUMP -// JUMPDEST -// ADDRESS -// POP -// DUP3 -// DUP2 -// SSTORE -// POP -// CALLVALUE -// POP -// PUSH1 0x0 -// DUP2 -// SWAP1 -// POP -// JUMPDEST -// SWAP3 -// SWAP2 -// POP -// POP -// JUMP -// JUMPDEST +// /* "":0:88 */ +// stop +// /* "":6:86 */ +// tag_1: +// swap2 +// swap1 +// swap2 +// /* "":37:46 */ +// address +// /* "":33:47 */ +// pop +// /* "":48:60 */ +// sstore +// /* "":65:76 */ +// callvalue +// /* "":61:77 */ +// pop +// /* "":6:86 */ +// swap1 +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse_without_retparams.yul b/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse_without_retparams.yul index d1f6b5bdc..385c253df 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse_without_retparams.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse_without_retparams.yul @@ -7,23 +7,31 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x17 -// JUMP -// JUMPDEST -// DUP1 -// PUSH1 0x80 -// MSTORE -// POP -// PUSH1 0x0 -// CALLDATALOAD -// ISZERO -// PUSH1 0x13 -// JUMPI -// DUP1 -// DUP2 -// SSTORE -// JUMPDEST -// POP -// JUMPDEST -// JUMP -// JUMPDEST +// /* "":0:88 */ +// stop +// /* "":4:86 */ +// tag_1: +// /* "":34:38 */ +// 0x80 +// /* "":27:42 */ +// mstore +// /* "":63:64 */ +// 0x00 +// /* "":50:65 */ +// calldataload +// /* "":47:82 */ +// tag_2 +// jumpi +// /* "":21:86 */ +// tag_3: +// /* "":4:86 */ +// pop +// jump // out +// /* "":66:82 */ +// tag_2: +// /* "":68:80 */ +// dup1 +// sstore +// /* "":66:82 */ +// codesize +// jump(tag_3) diff --git a/test/libyul/evmCodeTransform/stackReuse/function_call.yul b/test/libyul/evmCodeTransform/stackReuse/function_call.yul index c14ccff36..1abc8d8af 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_call.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_call.yul @@ -6,28 +6,35 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x9 -// PUSH1 0x2 -// PUSH1 0x1 -// PUSH1 0xD -// JUMP -// JUMPDEST -// PUSH1 0x15 -// JUMP -// JUMPDEST -// POP -// POP -// PUSH1 0x0 -// JUMPDEST -// SWAP1 -// JUMP -// JUMPDEST -// PUSH1 0x1F -// PUSH1 0x4 -// PUSH1 0x3 -// PUSH1 0xD -// JUMP -// JUMPDEST -// SWAP1 -// POP -// POP +// /* "":15:22 */ +// tag_1 +// /* "":20:21 */ +// 0x02 +// /* "":17:18 */ +// 0x01 +// /* "":15:22 */ +// tag_2 +// jump // in +// tag_1: +// /* "":62:69 */ +// pop +// tag_3 +// /* "":67:68 */ +// 0x04 +// /* "":64:65 */ +// 0x03 +// /* "":62:69 */ +// tag_2 +// jump // in +// tag_3: +// /* "":0:71 */ +// stop +// /* "":27:52 */ +// tag_2: +// pop +// pop +// /* "":47:48 */ +// 0x00 +// /* "":27:52 */ +// swap1 +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_many_arguments.yul b/test/libyul/evmCodeTransform/stackReuse/function_many_arguments.yul index aa4567a90..17ccdd3ca 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_many_arguments.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_many_arguments.yul @@ -25,92 +25,86 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x80 -// JUMP -// JUMPDEST -// DUP1 -// PUSH2 0x100 -// MSTORE -// POP -// DUP1 -// PUSH2 0x120 -// MSTORE -// POP -// DUP1 -// PUSH2 0x140 -// MSTORE -// POP -// DUP1 -// PUSH2 0x160 -// MSTORE -// POP -// DUP1 -// PUSH2 0x180 -// MSTORE -// POP -// DUP1 -// PUSH2 0x1A0 -// MSTORE -// POP -// DUP1 -// PUSH2 0x1C0 -// MSTORE -// POP -// DUP1 -// PUSH2 0x1E0 -// MSTORE -// POP -// DUP1 -// PUSH2 0x200 -// MSTORE -// POP -// DUP1 -// PUSH2 0x220 -// MSTORE -// POP -// DUP1 -// PUSH2 0x240 -// MSTORE -// POP -// DUP1 -// PUSH2 0x260 -// MSTORE -// POP -// DUP1 -// PUSH2 0x280 -// MSTORE -// POP -// DUP1 -// PUSH2 0x2A0 -// MSTORE -// POP -// DUP1 -// PUSH2 0x2C0 -// MSTORE -// POP -// DUP1 -// PUSH2 0x2E0 -// MSTORE -// POP -// DUP1 -// PUSH2 0x300 -// MSTORE -// POP -// DUP1 -// PUSH2 0x320 -// MSTORE -// POP -// DUP1 -// PUSH2 0x340 -// MSTORE -// POP -// PUSH1 0x0 -// DUP2 -// SWAP1 -// POP -// JUMPDEST -// SWAP2 -// SWAP1 -// POP -// JUMP -// JUMPDEST +// /* "":0:662 */ +// stop +// /* "":6:660 */ +// tag_1: +// /* "":130:136 */ +// 0x0100 +// /* "":123:141 */ +// mstore +// /* "":157:163 */ +// 0x0120 +// /* "":150:168 */ +// mstore +// /* "":184:190 */ +// 0x0140 +// /* "":177:195 */ +// mstore +// /* "":211:217 */ +// 0x0160 +// /* "":204:222 */ +// mstore +// /* "":238:244 */ +// 0x0180 +// /* "":231:249 */ +// mstore +// /* "":265:271 */ +// 0x01a0 +// /* "":258:276 */ +// mstore +// /* "":292:298 */ +// 0x01c0 +// /* "":285:303 */ +// mstore +// /* "":319:325 */ +// 0x01e0 +// /* "":312:330 */ +// mstore +// /* "":346:352 */ +// 0x0200 +// /* "":339:357 */ +// mstore +// /* "":373:379 */ +// 0x0220 +// /* "":366:385 */ +// mstore +// /* "":401:407 */ +// 0x0240 +// /* "":394:413 */ +// mstore +// /* "":429:435 */ +// 0x0260 +// /* "":422:441 */ +// mstore +// /* "":457:463 */ +// 0x0280 +// /* "":450:469 */ +// mstore +// /* "":485:491 */ +// 0x02a0 +// /* "":478:497 */ +// mstore +// /* "":513:519 */ +// 0x02c0 +// /* "":506:525 */ +// mstore +// /* "":541:547 */ +// 0x02e0 +// /* "":534:553 */ +// mstore +// /* "":569:575 */ +// 0x0300 +// /* "":562:581 */ +// mstore +// /* "":597:603 */ +// 0x0320 +// /* "":590:609 */ +// mstore +// /* "":625:631 */ +// 0x0340 +// /* "":618:637 */ +// mstore +// /* "":6:660 */ +// swap1 +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_params.yul b/test/libyul/evmCodeTransform/stackReuse/function_params.yul index 60139bb76..e8d9bb30c 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_params.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_params.yul @@ -4,11 +4,10 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x8 -// JUMP -// JUMPDEST -// POP -// POP -// JUMPDEST -// JUMP -// JUMPDEST +// /* "":0:28 */ +// stop +// /* "":6:26 */ +// tag_1: +// pop +// pop +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams.yul b/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams.yul index 3228637dc..529203400 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams.yul @@ -8,17 +8,18 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x10 -// JUMP -// JUMPDEST -// POP -// POP -// POP -// POP -// PUSH1 0x0 -// PUSH1 0x0 -// JUMPDEST -// SWAP1 -// SWAP2 -// JUMP -// JUMPDEST +// /* "":212:254 */ +// stop +// /* "":218:252 */ +// tag_1: +// pop +// pop +// pop +// pop +// /* "":247:248 */ +// 0x00 +// /* "":244:245 */ +// 0x00 +// /* "":218:252 */ +// swap2 +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams_partly_used.yul b/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams_partly_used.yul index 089892a66..d0fc0506f 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams_partly_used.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams_partly_used.yul @@ -4,28 +4,31 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x1E -// JUMP -// JUMPDEST -// POP -// PUSH1 0x3 -// SWAP1 -// POP -// POP -// POP -// POP -// PUSH1 0x0 -// PUSH1 0x0 -// PUSH1 0x9 -// PUSH1 0x2 -// SWAP2 -// POP -// DUP2 -// DUP2 -// MSTORE -// POP -// JUMPDEST -// SWAP1 -// SWAP2 -// JUMP -// JUMPDEST +// /* "":0:80 */ +// stop +// /* "":6:78 */ +// tag_1: +// pop +// pop +// pop +// pop +// /* "":32:33 */ +// 0x00 +// /* "":6:78 */ +// swap1 +// /* "":44:45 */ +// 0x03 +// /* "":46:56 */ +// pop +// /* "":55:56 */ +// 0x09 +// /* "":57:63 */ +// swap1 +// /* "":62:63 */ +// 0x02 +// /* "":64:76 */ +// dup1 +// swap3 +// mstore +// /* "":6:78 */ +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam.yul index 4dde5208b..bee0d3f63 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam.yul @@ -4,13 +4,14 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0xC -// JUMP -// JUMPDEST -// PUSH1 0x0 -// PUSH1 0x0 -// JUMPDEST -// SWAP1 -// SWAP2 -// JUMP -// JUMPDEST +// /* "":0:32 */ +// stop +// /* "":6:30 */ +// tag_1: +// /* "":25:26 */ +// 0x00 +// /* "":22:23 */ +// 0x00 +// /* "":6:30 */ +// swap2 +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_block.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_block.yul index 3c1d90bd3..5a9e7704e 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_block.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_block.yul @@ -4,15 +4,21 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0xD -// JUMP -// JUMPDEST -// ADDRESS -// POP -// PUSH1 0x0 -// CALLVALUE -// POP -// JUMPDEST -// SWAP1 -// JUMP -// JUMPDEST +// /* "":0:65 */ +// stop +// /* "":6:63 */ +// tag_1: +// /* "":22:23 */ +// 0x00 +// /* "":6:63 */ +// swap1 +// /* "":30:39 */ +// address +// /* "":26:40 */ +// pop +// /* "":47:58 */ +// callvalue +// /* "":43:59 */ +// pop +// /* "":6:63 */ +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_declaration.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_declaration.yul index fe99402f4..97bffac38 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_declaration.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_declaration.yul @@ -4,15 +4,20 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0xD -// JUMP -// JUMPDEST -// ADDRESS -// POP -// PUSH1 0x0 -// CALLVALUE -// POP -// JUMPDEST -// SWAP1 -// JUMP -// JUMPDEST +// /* "":0:65 */ +// stop +// /* "":6:63 */ +// tag_1: +// /* "":22:23 */ +// 0x00 +// /* "":6:63 */ +// swap1 +// /* "":30:39 */ +// address +// /* "":26:40 */ +// pop +// /* "":50:61 */ +// callvalue +// /* "":6:63 */ +// pop +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_for.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_for.yul index 7dcb39c10..c18fb7c37 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_for.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_for.yul @@ -4,24 +4,21 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x19 -// JUMP -// JUMPDEST -// ADDRESS -// POP -// PUSH1 0x0 -// CALLVALUE -// POP -// JUMPDEST -// PUSH1 0x0 -// ISZERO -// PUSH1 0x15 -// JUMPI -// JUMPDEST -// PUSH1 0xA -// JUMP -// JUMPDEST -// JUMPDEST -// SWAP1 -// JUMP -// JUMPDEST +// /* "":0:78 */ +// stop +// /* "":6:76 */ +// tag_1: +// /* "":22:23 */ +// 0x00 +// /* "":6:76 */ +// swap1 +// /* "":30:39 */ +// address +// /* "":26:40 */ +// pop +// /* "":51:62 */ +// callvalue +// /* "":47:63 */ +// pop +// /* "":6:76 */ +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_if.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_if.yul index bd882240f..08dda5a3b 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_if.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_if.yul @@ -4,20 +4,32 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x14 -// JUMP -// JUMPDEST -// ADDRESS -// POP -// PUSH1 0x0 -// PUSH1 0x1 -// ISZERO -// PUSH1 0x10 -// JUMPI -// CALLVALUE -// POP -// JUMPDEST -// JUMPDEST -// SWAP1 -// JUMP -// JUMPDEST +// /* "":0:70 */ +// stop +// /* "":6:68 */ +// tag_1: +// /* "":22:23 */ +// 0x00 +// /* "":6:68 */ +// swap1 +// /* "":44:45 */ +// 0x01 +// /* "":30:39 */ +// address +// /* "":26:40 */ +// pop +// /* "":41:66 */ +// tag_2 +// jumpi +// /* "":24:68 */ +// tag_3: +// /* "":6:68 */ +// jump // out +// /* "":46:66 */ +// tag_2: +// /* "":52:63 */ +// callvalue +// /* "":48:64 */ +// pop +// /* "":46:66 */ +// jump(tag_3) diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_leave.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_leave.yul index 2e16c05d5..9ac0c00bf 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_leave.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_leave.yul @@ -4,17 +4,17 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x10 -// JUMP -// JUMPDEST -// ADDRESS -// POP -// PUSH1 0x0 -// PUSH1 0xD -// JUMP -// CALLVALUE -// POP -// JUMPDEST -// SWAP1 -// JUMP -// JUMPDEST +// /* "":0:67 */ +// stop +// /* "":6:65 */ +// tag_1: +// /* "":22:23 */ +// 0x00 +// /* "":6:65 */ +// swap1 +// /* "":30:39 */ +// address +// /* "":26:40 */ +// pop +// /* "":41:46 */ +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_read.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_read.yul index d8440b86e..fcc8278e6 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_read.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_read.yul @@ -4,18 +4,27 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x11 -// JUMP -// JUMPDEST -// ADDRESS -// POP -// PUSH1 0x0 -// DUP1 -// PUSH1 0x0 -// SSTORE -// CALLVALUE -// POP -// JUMPDEST -// SWAP1 -// JUMP -// JUMPDEST +// /* "":0:74 */ +// stop +// /* "":6:72 */ +// tag_1: +// /* "":22:23 */ +// 0x00 +// /* "":6:72 */ +// swap1 +// /* "":30:39 */ +// address +// /* "":26:40 */ +// pop +// /* "":41:53 */ +// dup2 +// /* "":48:49 */ +// 0x00 +// /* "":41:53 */ +// sstore +// /* "":58:69 */ +// callvalue +// /* "":54:70 */ +// pop +// /* "":6:72 */ +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned.yul index c20158eae..1cc19a464 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned.yul @@ -4,13 +4,17 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0xB -// JUMP -// JUMPDEST -// CALLVALUE -// POP -// PUSH1 0x0 -// JUMPDEST -// SWAP1 -// JUMP -// JUMPDEST +// /* "":0:46 */ +// stop +// /* "":6:44 */ +// tag_1: +// /* "":22:23 */ +// 0x00 +// /* "":6:44 */ +// swap1 +// /* "":30:41 */ +// callvalue +// /* "":26:42 */ +// pop +// /* "":6:44 */ +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned_multiple.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned_multiple.yul index d9e80547e..e44e3b437 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned_multiple.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned_multiple.yul @@ -4,17 +4,21 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x11 -// JUMP -// JUMPDEST -// CALLVALUE -// POP -// PUSH1 0x0 -// PUSH1 0x0 -// PUSH1 0x0 -// JUMPDEST -// SWAP1 -// SWAP2 -// SWAP3 -// JUMP -// JUMPDEST +// /* "":0:52 */ +// stop +// /* "":6:50 */ +// tag_1: +// /* "":25:26 */ +// 0x00 +// /* "":28:29 */ +// 0x00 +// /* "":22:23 */ +// 0x00 +// /* "":6:50 */ +// swap3 +// /* "":36:47 */ +// callvalue +// /* "":32:48 */ +// pop +// /* "":6:50 */ +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_trivial.yul b/test/libyul/evmCodeTransform/stackReuse/function_trivial.yul index 2c803e85f..3d6286efd 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_trivial.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_trivial.yul @@ -4,9 +4,8 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x6 -// JUMP -// JUMPDEST -// JUMPDEST -// JUMP -// JUMPDEST +// /* "":0:22 */ +// stop +// /* "":4:20 */ +// tag_1: +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_with_body_embedded.yul b/test/libyul/evmCodeTransform/stackReuse/function_with_body_embedded.yul index 60f287734..f8480bc91 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_with_body_embedded.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_with_body_embedded.yul @@ -9,27 +9,22 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x3 -// PUSH1 0x17 -// JUMP -// JUMPDEST -// PUSH1 0x0 -// DUP2 -// POP -// PUSH1 0x3 -// SWAP2 -// POP -// DUP2 -// SWAP1 -// POP -// JUMPDEST -// SWAP3 -// SWAP2 -// POP -// POP -// JUMP -// JUMPDEST -// PUSH1 0x7 -// SWAP1 -// POP -// POP +// /* "":15:16 */ +// 0x03 +// /* "":177:183 */ +// pop +// /* "":182:183 */ +// 0x07 +// /* "":0:185 */ +// stop +// /* "":21:172 */ +// tag_1: +// swap1 +// pop +// /* "":153:159 */ +// pop +// /* "":158:159 */ +// 0x03 +// /* "":21:172 */ +// swap1 +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/functions_multi_return.yul b/test/libyul/evmCodeTransform/stackReuse/functions_multi_return.yul index 6189e1614..df8b96184 100644 --- a/test/libyul/evmCodeTransform/stackReuse/functions_multi_return.yul +++ b/test/libyul/evmCodeTransform/stackReuse/functions_multi_return.yul @@ -10,51 +10,62 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x14 -// JUMP -// JUMPDEST -// POP -// POP -// PUSH1 0x0 -// JUMPDEST -// SWAP1 -// JUMP -// JUMPDEST -// PUSH1 0x0 -// PUSH1 0x0 -// JUMPDEST -// SWAP1 -// SWAP2 -// JUMP -// JUMPDEST -// PUSH1 0x1E -// PUSH1 0x2 -// PUSH1 0x1 -// PUSH1 0x3 -// JUMP -// JUMPDEST -// PUSH1 0x28 -// PUSH1 0x4 -// PUSH1 0x3 -// PUSH1 0x3 -// JUMP -// JUMPDEST -// SWAP1 -// POP -// POP -// PUSH1 0x31 -// PUSH1 0xB -// JUMP -// JUMPDEST -// PUSH1 0x37 -// PUSH1 0xB -// JUMP -// JUMPDEST -// SWAP2 -// POP -// SWAP2 -// POP -// POP -// POP -// PUSH1 0x7 -// POP +// /* "":74:81 */ +// tag_1 +// /* "":79:80 */ +// 0x02 +// /* "":76:77 */ +// 0x01 +// /* "":74:81 */ +// tag_2 +// jump // in +// tag_1: +// /* "":91:98 */ +// pop +// tag_3 +// /* "":96:97 */ +// 0x04 +// /* "":93:94 */ +// 0x03 +// /* "":91:98 */ +// tag_2 +// jump // in +// tag_3: +// /* "":115:118 */ +// pop +// tag_4 +// tag_5 +// jump // in +// tag_4: +// /* "":131:134 */ +// pop +// pop +// tag_6 +// tag_5 +// jump // in +// tag_6: +// /* "":139:154 */ +// pop +// pop +// /* "":153:154 */ +// 0x07 +// /* "":0:156 */ +// stop +// /* "":6:31 */ +// tag_2: +// pop +// pop +// /* "":26:27 */ +// 0x00 +// /* "":6:31 */ +// swap1 +// jump // out +// /* "":36:60 */ +// tag_5: +// /* "":55:56 */ +// 0x00 +// /* "":52:53 */ +// 0x00 +// /* "":36:60 */ +// swap2 +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/if.yul b/test/libyul/evmCodeTransform/stackReuse/if.yul index a407bb54c..cf0b2a044 100644 --- a/test/libyul/evmCodeTransform/stackReuse/if.yul +++ b/test/libyul/evmCodeTransform/stackReuse/if.yul @@ -3,15 +3,22 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x0 -// MLOAD -// DUP1 -// ISZERO -// PUSH1 0xA -// JUMPI -// DUP1 -// POP -// JUMPDEST -// POP -// PUSH1 0x3 -// POP +// /* "":72:73 */ +// 0x00 +// /* "":66:74 */ +// mload +// /* "":75:94 */ +// dup1 +// tag_1 +// jumpi +// /* "":55:107 */ +// tag_2: +// /* "":95:105 */ +// pop +// /* "":104:105 */ +// 0x03 +// /* "":55:107 */ +// stop +// /* "":80:94 */ +// tag_1: +// jump(tag_2) diff --git a/test/libyul/evmCodeTransform/stackReuse/last_use_in_nested_block.yul b/test/libyul/evmCodeTransform/stackReuse/last_use_in_nested_block.yul index 1fc780d21..49ffb3971 100644 --- a/test/libyul/evmCodeTransform/stackReuse/last_use_in_nested_block.yul +++ b/test/libyul/evmCodeTransform/stackReuse/last_use_in_nested_block.yul @@ -2,9 +2,11 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x0 -// DUP1 -// POP -// POP -// PUSH1 0x1 -// POP +// /* "":11:12 */ +// 0x00 +// /* "":15:21 */ +// pop +// /* "":33:34 */ +// 0x01 +// /* "":0:36 */ +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/multi_reuse_same_variable_name.yul b/test/libyul/evmCodeTransform/stackReuse/multi_reuse_same_variable_name.yul index 88d42510c..3404dc536 100644 --- a/test/libyul/evmCodeTransform/stackReuse/multi_reuse_same_variable_name.yul +++ b/test/libyul/evmCodeTransform/stackReuse/multi_reuse_same_variable_name.yul @@ -2,22 +2,25 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x0 -// MLOAD -// PUSH1 0x1 -// PUSH1 0x6 -// SWAP1 -// POP -// DUP1 -// SWAP2 -// POP -// POP -// PUSH1 0x2 -// DUP1 -// SWAP2 -// POP -// PUSH1 0x4 -// SWAP1 -// POP -// POP -// POP +// /* "":17:18 */ +// 0x00 +// /* "":11:19 */ +// mload +// /* "":22:32 */ +// pop +// /* "":31:32 */ +// 0x01 +// /* "":33:39 */ +// pop +// /* "":38:39 */ +// 0x06 +// /* "":51:61 */ +// pop +// /* "":60:61 */ +// 0x02 +// /* "":69:75 */ +// pop +// /* "":74:75 */ +// 0x04 +// /* "":0:79 */ +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/multi_reuse_single_slot.yul b/test/libyul/evmCodeTransform/stackReuse/multi_reuse_single_slot.yul index ba0ad96e7..a80e66c10 100644 --- a/test/libyul/evmCodeTransform/stackReuse/multi_reuse_single_slot.yul +++ b/test/libyul/evmCodeTransform/stackReuse/multi_reuse_single_slot.yul @@ -2,13 +2,19 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x1 -// PUSH1 0x6 -// SWAP1 -// POP -// POP -// PUSH1 0x2 -// PUSH1 0x4 -// SWAP1 -// POP -// POP +// /* "":11:12 */ +// 0x01 +// /* "":13:19 */ +// pop +// /* "":18:19 */ +// 0x06 +// /* "":20:30 */ +// pop +// /* "":29:30 */ +// 0x02 +// /* "":31:37 */ +// pop +// /* "":36:37 */ +// 0x04 +// /* "":0:39 */ +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/multi_reuse_single_slot_nested.yul b/test/libyul/evmCodeTransform/stackReuse/multi_reuse_single_slot_nested.yul index b064fcc20..db8783502 100644 --- a/test/libyul/evmCodeTransform/stackReuse/multi_reuse_single_slot_nested.yul +++ b/test/libyul/evmCodeTransform/stackReuse/multi_reuse_single_slot_nested.yul @@ -2,13 +2,19 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x1 -// PUSH1 0x6 -// SWAP1 -// POP -// POP -// PUSH1 0x2 -// PUSH1 0x4 -// SWAP1 -// POP -// POP +// /* "":11:12 */ +// 0x01 +// /* "":13:19 */ +// pop +// /* "":18:19 */ +// 0x06 +// /* "":22:32 */ +// pop +// /* "":31:32 */ +// 0x02 +// /* "":33:39 */ +// pop +// /* "":38:39 */ +// 0x04 +// /* "":0:43 */ +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_not_same_scope.yul b/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_not_same_scope.yul index fe50cb997..9be91989d 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_not_same_scope.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_not_same_scope.yul @@ -8,10 +8,10 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x5 -// DUP1 -// DUP1 -// DUP2 -// SSTORE -// POP -// POP +// /* "":15:16 */ +// 0x05 +// /* "":126:138 */ +// dup1 +// sstore +// /* "":0:146 */ +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_last_used.yul b/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_last_used.yul index 5e4cfd093..11e77c626 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_last_used.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_last_used.yul @@ -6,11 +6,10 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x5 -// DUP1 -// SWAP1 -// POP -// DUP1 -// DUP2 -// SSTORE -// POP +// /* "":15:16 */ +// 0x05 +// /* "":74:86 */ +// dup1 +// sstore +// /* "":0:88 */ +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_last_used_expr.yul b/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_last_used_expr.yul index 89a82f65c..214020ccd 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_last_used_expr.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_last_used_expr.yul @@ -6,13 +6,14 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x5 -// PUSH1 0x2 -// DUP2 -// ADD -// SWAP1 -// POP -// DUP1 -// DUP2 -// SSTORE -// POP +// /* "":37:38 */ +// 0x02 +// /* "":15:16 */ +// 0x05 +// /* "":30:39 */ +// add +// /* "":82:94 */ +// dup1 +// sstore +// /* "":0:96 */ +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_not_last_used.yul b/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_not_last_used.yul index 7c7cdfd55..e3002f34d 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_not_last_used.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_not_last_used.yul @@ -6,10 +6,11 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x5 -// DUP1 -// DUP2 -// DUP2 -// SSTORE -// POP -// POP +// /* "":15:16 */ +// 0x05 +// /* "":21:31 */ +// dup1 +// /* "":107:119 */ +// sstore +// /* "":0:121 */ +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/reuse_slots.yul b/test/libyul/evmCodeTransform/stackReuse/reuse_slots.yul index 44b916670..13decd323 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_slots.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_slots.yul @@ -2,22 +2,26 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x0 -// PUSH1 0x0 -// PUSH1 0x0 -// PUSH1 0x0 -// POP -// PUSH1 0x2 -// SWAP2 -// POP -// PUSH1 0x3 -// DUP4 -// DUP4 -// MSTORE -// DUP2 -// DUP2 -// MSTORE -// POP -// POP -// POP -// POP +// /* "":2:16 */ +// 0x00 +// dup1 +// dup1 +// dup1 +// /* "":17:27 */ +// pop +// swap2 +// swap1 +// pop +// /* "":26:27 */ +// 0x02 +// /* "":28:38 */ +// swap1 +// /* "":37:38 */ +// 0x03 +// /* "":39:51 */ +// swap2 +// mstore +// /* "":52:64 */ +// mstore +// /* "":0:66 */ +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function.yul b/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function.yul index f5e855a46..a7a8b1a02 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function.yul @@ -5,36 +5,39 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x12 -// JUMP -// JUMPDEST -// PUSH1 0x0 -// PUSH1 0x0 -// PUSH1 0x0 -// PUSH1 0x0 -// JUMPDEST -// SWAP1 -// SWAP2 -// SWAP3 -// SWAP4 -// JUMP -// JUMPDEST -// PUSH1 0x18 -// PUSH1 0x3 -// JUMP -// JUMPDEST -// POP -// PUSH1 0x2 -// SWAP2 -// POP -// PUSH1 0x3 -// DUP4 -// DUP4 -// MSTORE -// DUP2 -// DUP2 -// MSTORE -// POP -// POP -// POP -// POP +// /* "":58:61 */ +// tag_1 +// tag_2 +// jump // in +// tag_1: +// /* "":62:73 */ +// pop +// swap2 +// swap1 +// pop +// /* "":72:73 */ +// 0x02 +// /* "":74:85 */ +// swap1 +// /* "":84:85 */ +// 0x03 +// /* "":86:99 */ +// swap2 +// mstore +// /* "":100:113 */ +// mstore +// /* "":0:115 */ +// stop +// /* "":6:35 */ +// tag_2: +// /* "":25:26 */ +// 0x00 +// /* "":28:29 */ +// 0x00 +// /* "":31:32 */ +// 0x00 +// /* "":22:23 */ +// 0x00 +// /* "":6:35 */ +// swap4 +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function_with_gaps.yul b/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function_with_gaps.yul index 36800b204..888bccf7d 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function_with_gaps.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function_with_gaps.yul @@ -9,42 +9,41 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x5 -// PUSH1 0x6 -// PUSH1 0x7 -// DUP2 -// DUP4 -// MSTORE -// PUSH1 0x1B -// JUMP -// JUMPDEST -// PUSH1 0x0 -// PUSH1 0x0 -// PUSH1 0x0 -// PUSH1 0x0 -// JUMPDEST -// SWAP1 -// SWAP2 -// SWAP3 -// SWAP4 -// JUMP -// JUMPDEST -// PUSH1 0x21 -// PUSH1 0xC -// JUMP -// JUMPDEST -// SWAP6 -// POP -// SWAP4 -// POP -// POP -// DUP1 -// DUP3 -// MSTORE -// POP -// POP -// DUP2 -// DUP2 -// MSTORE -// POP -// POP +// /* "":106:107 */ +// 0x05 +// /* "":118:119 */ +// 0x06 +// /* "":130:131 */ +// 0x07 +// /* "":136:150 */ +// swap2 +// mstore +// /* "":207:210 */ +// tag_1 +// tag_2 +// jump // in +// tag_1: +// /* "":211:224 */ +// swap4 +// swap1 +// swap3 +// swap2 +// pop +// mstore +// /* "":225:237 */ +// mstore +// /* "":0:239 */ +// stop +// /* "":155:184 */ +// tag_2: +// /* "":174:175 */ +// 0x00 +// /* "":177:178 */ +// 0x00 +// /* "":180:181 */ +// 0x00 +// /* "":171:172 */ +// 0x00 +// /* "":155:184 */ +// swap4 +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/reuse_too_deep_slot.yul b/test/libyul/evmCodeTransform/stackReuse/reuse_too_deep_slot.yul index badcc0969..2adfe7892 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_too_deep_slot.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_too_deep_slot.yul @@ -33,78 +33,108 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x7 -// PUSH1 0x42 -// DUP16 -// PUSH1 0x0 -// SSTORE -// PUSH1 0x43 -// DUP2 -// PUSH1 0x1 -// MSTORE -// DUP1 -// PUSH1 0x1 -// MSTORE -// POP -// POP -// DUP15 -// PUSH1 0x1 -// SSTORE -// DUP14 -// PUSH1 0x1 -// SSTORE -// DUP13 -// PUSH1 0x1 -// SSTORE -// DUP12 -// PUSH1 0x1 -// SSTORE -// DUP11 -// PUSH1 0x1 -// SSTORE -// DUP10 -// PUSH1 0x1 -// SSTORE -// DUP9 -// PUSH1 0x1 -// SSTORE -// DUP8 -// PUSH1 0x1 -// SSTORE -// DUP7 -// PUSH1 0x1 -// SSTORE -// DUP6 -// PUSH1 0x1 -// SSTORE -// DUP5 -// PUSH1 0x1 -// SSTORE -// DUP4 -// PUSH1 0x1 -// SSTORE -// DUP3 -// PUSH1 0x1 -// SSTORE -// DUP2 -// PUSH1 0x1 -// SSTORE -// DUP1 -// PUSH1 0x1 -// SSTORE -// POP -// POP -// POP -// POP -// POP -// POP -// POP -// POP -// POP -// POP -// POP -// POP -// POP -// POP -// POP -// POP +// /* "":15:16 */ +// 0x07 +// /* "":94:121 */ +// verbatimbytecode_6042 +// /* "":280:291 */ +// swap15 +// /* "":287:288 */ +// 0x00 +// /* "":280:291 */ +// swap15 +// swap2 +// swap15 +// swap14 +// swap3 +// swap14 +// swap13 +// swap4 +// swap13 +// swap12 +// swap5 +// swap12 +// swap11 +// swap6 +// swap11 +// swap10 +// swap7 +// swap10 +// swap9 +// swap8 +// swap9 +// sstore +// /* "":370:396 */ +// verbatimbytecode_6043 +// /* "":514:527 */ +// swap1 +// /* "":521:522 */ +// 0x01 +// /* "":514:527 */ +// mstore +// /* "":539:540 */ +// 0x01 +// /* "":532:545 */ +// mstore +// /* "":653:654 */ +// 0x01 +// /* "":646:659 */ +// sstore +// /* "":671:672 */ +// 0x01 +// /* "":664:677 */ +// sstore +// /* "":689:690 */ +// 0x01 +// /* "":682:695 */ +// sstore +// /* "":707:708 */ +// 0x01 +// /* "":700:713 */ +// sstore +// /* "":725:726 */ +// 0x01 +// /* "":718:731 */ +// sstore +// /* "":743:744 */ +// 0x01 +// /* "":736:749 */ +// sstore +// /* "":761:762 */ +// 0x01 +// /* "":754:767 */ +// sstore +// /* "":779:780 */ +// 0x01 +// /* "":772:785 */ +// sstore +// /* "":797:798 */ +// 0x01 +// /* "":790:803 */ +// sstore +// /* "":815:816 */ +// 0x01 +// /* "":808:822 */ +// sstore +// /* "":834:835 */ +// 0x01 +// /* "":827:841 */ +// sstore +// /* "":853:854 */ +// 0x01 +// /* "":846:860 */ +// sstore +// /* "":872:873 */ +// 0x01 +// /* "":865:879 */ +// sstore +// /* "":891:892 */ +// 0x01 +// /* "":884:898 */ +// sstore +// /* "":910:911 */ +// 0x01 +// /* "":903:917 */ +// sstore +// /* "":0:919 */ +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/single_var.yul b/test/libyul/evmCodeTransform/stackReuse/single_var.yul index 06957305e..09a0d6fee 100644 --- a/test/libyul/evmCodeTransform/stackReuse/single_var.yul +++ b/test/libyul/evmCodeTransform/stackReuse/single_var.yul @@ -2,5 +2,7 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x0 -// POP +// /* "":2:7 */ +// 0x00 +// /* "":0:9 */ +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/single_var_assigned.yul b/test/libyul/evmCodeTransform/stackReuse/single_var_assigned.yul index 6bc5f504f..ed497467d 100644 --- a/test/libyul/evmCodeTransform/stackReuse/single_var_assigned.yul +++ b/test/libyul/evmCodeTransform/stackReuse/single_var_assigned.yul @@ -2,5 +2,7 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x1 -// POP +// /* "":11:12 */ +// 0x01 +// /* "":0:14 */ +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/single_var_assigned_plus_code.yul b/test/libyul/evmCodeTransform/stackReuse/single_var_assigned_plus_code.yul index 9fdccea85..bec4c834f 100644 --- a/test/libyul/evmCodeTransform/stackReuse/single_var_assigned_plus_code.yul +++ b/test/libyul/evmCodeTransform/stackReuse/single_var_assigned_plus_code.yul @@ -2,8 +2,15 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x1 -// POP -// PUSH1 0x4 -// PUSH1 0x3 -// MSTORE +// /* "":11:12 */ +// 0x01 +// /* "":13:25 */ +// pop +// /* "":23:24 */ +// 0x04 +// /* "":20:21 */ +// 0x03 +// /* "":13:25 */ +// mstore +// /* "":0:27 */ +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/single_var_assigned_plus_code_and_reused.yul b/test/libyul/evmCodeTransform/stackReuse/single_var_assigned_plus_code_and_reused.yul index 2d66c74db..b9a814700 100644 --- a/test/libyul/evmCodeTransform/stackReuse/single_var_assigned_plus_code_and_reused.yul +++ b/test/libyul/evmCodeTransform/stackReuse/single_var_assigned_plus_code_and_reused.yul @@ -2,11 +2,17 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x1 -// PUSH1 0x4 -// PUSH1 0x3 -// MSTORE -// DUP1 -// MLOAD -// POP -// POP +// /* "":11:12 */ +// 0x01 +// /* "":23:24 */ +// 0x04 +// /* "":20:21 */ +// 0x03 +// /* "":13:25 */ +// mstore +// /* "":30:38 */ +// mload +// /* "":26:39 */ +// pop +// /* "":0:41 */ +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/smoke.yul b/test/libyul/evmCodeTransform/stackReuse/smoke.yul index 0a212e9ca..aa46f7a4a 100644 --- a/test/libyul/evmCodeTransform/stackReuse/smoke.yul +++ b/test/libyul/evmCodeTransform/stackReuse/smoke.yul @@ -2,3 +2,5 @@ // ==== // stackOptimization: true // ---- +// /* "":0:2 */ +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/switch.yul b/test/libyul/evmCodeTransform/stackReuse/switch.yul index 480343dcc..f72d80fad 100644 --- a/test/libyul/evmCodeTransform/stackReuse/switch.yul +++ b/test/libyul/evmCodeTransform/stackReuse/switch.yul @@ -2,25 +2,34 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x0 -// DUP1 -// PUSH1 0x0 -// DUP2 -// EQ -// PUSH1 0x11 -// JUMPI -// PUSH1 0x3 -// SWAP2 -// POP -// PUSH1 0x18 -// JUMP -// JUMPDEST -// PUSH1 0x2 -// POP -// PUSH1 0x3 -// POP -// JUMPDEST -// POP -// POP -// PUSH1 0x9 -// POP +// /* "":11:12 */ +// 0x00 +// /* "":27:28 */ +// 0x00 +// /* "":22:54 */ +// eq +// tag_1 +// jumpi +// /* "":13:73 */ +// tag_2: +// /* "":70:71 */ +// 0x03 +// /* "":63:73 */ +// pop +// /* "":13:73 */ +// tag_3: +// /* "":83:84 */ +// 0x09 +// /* "":13:73 */ +// stop +// /* "":29:54 */ +// tag_1: +// /* "":40:41 */ +// 0x02 +// /* "":42:52 */ +// pop +// /* "":51:52 */ +// 0x03 +// /* "":29:54 */ +// pop +// jump(tag_3) diff --git a/test/libyul/evmCodeTransform/stub.yul b/test/libyul/evmCodeTransform/stub.yul new file mode 100644 index 000000000..a11cad44c --- /dev/null +++ b/test/libyul/evmCodeTransform/stub.yul @@ -0,0 +1,86 @@ +{ + fun_c() + function fun_c() + { + switch iszero(calldataload(0)) + case 0 { } + default { + if calldataload(1) + { + leave + } + if calldataload(2) + { + revert(0, 0) + } + } + revert(0, 0) + } +} +// ==== +// stackOptimization: true +// ---- +// /* "":14:21 */ +// tag_1 +// tag_2 +// jump // in +// tag_1: +// /* "":0:460 */ +// stop +// /* "":34:458 */ +// tag_2: +// /* "":108:109 */ +// 0x00 +// /* "":95:110 */ +// calldataload +// /* "":88:111 */ +// iszero +// /* "":133:134 */ +// 0x00 +// /* "":128:138 */ +// eq +// tag_3 +// jumpi +// /* "":81:415 */ +// tag_4: +// /* "":201:202 */ +// 0x01 +// /* "":188:203 */ +// calldataload +// /* "":185:277 */ +// tag_5 +// jumpi +// /* "":81:415 */ +// tag_6: +// /* "":301:316 */ +// pop +// /* "":314:315 */ +// 0x02 +// /* "":301:316 */ +// calldataload +// /* "":298:397 */ +// tag_7 +// jumpi +// /* "":81:415 */ +// tag_8: +// tag_9: +// /* "":442:443 */ +// 0x00 +// /* "":432:444 */ +// dup1 +// revert +// /* "":337:397 */ +// tag_7: +// /* "":373:374 */ +// 0x00 +// /* "":363:375 */ +// dup1 +// revert +// /* "":224:277 */ +// tag_5: +// /* "":250:255 */ +// jump // out +// /* "":135:138 */ +// tag_3: +// pop +// jump(tag_9) diff --git a/test/libyul/objectCompiler/long_object_name.yul b/test/libyul/objectCompiler/long_object_name.yul index ad8266d1e..67ef5e407 100644 --- a/test/libyul/objectCompiler/long_object_name.yul +++ b/test/libyul/objectCompiler/long_object_name.yul @@ -16,10 +16,14 @@ object "t" { // 0x00 // /* "source":23:147 */ // sstore +// /* "source":19:150 */ +// stop // stop // // sub_0: assembly { +// /* "source":272:274 */ +// stop // } -// Bytecode: 6000600055fe -// Opcodes: PUSH1 0x0 PUSH1 0x0 SSTORE INVALID -// SourceMappings: 33:113:0:-:0;30:1;23:124 +// Bytecode: 600160005500fe +// Opcodes: PUSH1 0x1 PUSH1 0x0 SSTORE STOP INVALID +// SourceMappings: 33:113:0:-:0;30:1;23:124;19:131 diff --git a/test/libyul/objectCompiler/nested_optimizer.yul b/test/libyul/objectCompiler/nested_optimizer.yul index e6f8b1f23..7b972286f 100644 --- a/test/libyul/objectCompiler/nested_optimizer.yul +++ b/test/libyul/objectCompiler/nested_optimizer.yul @@ -20,22 +20,26 @@ object "a" { // Assembly: // /* "source":48:49 */ // 0x00 -// dup1 // /* "source":35:50 */ +// dup1 // calldataload // /* "source":107:127 */ // sstore +// /* "source":20:131 */ +// stop // stop // // sub_0: assembly { // /* "source":188:189 */ // 0x00 -// dup1 // /* "source":175:190 */ +// dup1 // calldataload // /* "source":253:273 */ // sstore +// /* "source":158:279 */ +// stop // } -// Bytecode: 6000803555fe -// Opcodes: PUSH1 0x0 DUP1 CALLDATALOAD SSTORE INVALID -// SourceMappings: 48:1:0:-:0;;35:15;107:20 +// Bytecode: 600080355500fe +// Opcodes: PUSH1 0x0 DUP1 CALLDATALOAD SSTORE STOP INVALID +// SourceMappings: 48:1:0:-:0;35:15;;107:20;20:111 diff --git a/test/libyul/objectCompiler/simple_optimizer.yul b/test/libyul/objectCompiler/simple_optimizer.yul index cf7658ea0..47fa6553a 100644 --- a/test/libyul/objectCompiler/simple_optimizer.yul +++ b/test/libyul/objectCompiler/simple_optimizer.yul @@ -10,11 +10,13 @@ // Assembly: // /* "source":26:27 */ // 0x00 -// dup1 // /* "source":13:28 */ +// dup1 // calldataload // /* "source":79:99 */ // sstore -// Bytecode: 6000803555 -// Opcodes: PUSH1 0x0 DUP1 CALLDATALOAD SSTORE -// SourceMappings: 26:1:0:-:0;;13:15;79:20 +// /* "source":0:101 */ +// stop +// Bytecode: 600080355500 +// Opcodes: PUSH1 0x0 DUP1 CALLDATALOAD SSTORE STOP +// SourceMappings: 26:1:0:-:0;13:15;;79:20;0:101 diff --git a/test/libyul/yulOptimizerTests/fullSuite/aztec.yul b/test/libyul/yulOptimizerTests/fullSuite/aztec.yul index ae1ca7848..2b2205579 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/aztec.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/aztec.yul @@ -237,87 +237,85 @@ // { // mstore(0x80, 7673901602397024137095011250362199966051872585513276903826533215767972925880) // mstore(0xa0, 8489654445897228341090914135473290831551238522473825886865492707826370766375) -// let _1 := calldataload(0x04) -// let notes := add(0x04, _1) -// let m := calldataload(0x24) +// let notes := add(0x04, calldataload(0x04)) // let n := calldataload(notes) -// let _2 := 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001 -// let challenge := mod(calldataload(0x44), _2) -// if gt(m, n) +// if gt(calldataload(0x24), n) // { // mstore(0x00, 404) // revert(0x00, 0x20) // } // let kn := calldataload(add(calldatasize(), not(191))) -// mstore(0x2a0, caller()) +// let _1 := 0x2a0 +// mstore(_1, caller()) // mstore(0x2c0, kn) -// mstore(0x2e0, m) -// kn := mulmod(sub(_2, kn), challenge, _2) +// mstore(0x2e0, calldataload(0x24)) +// kn := mulmod(sub(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001, kn), mod(calldataload(0x44), 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001), 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001) // hashCommitments(notes, n) // let b := add(0x300, shl(7, n)) // let i := 0 // for { } lt(i, n) { i := add(i, 0x01) } // { -// let _3 := add(_1, mul(i, 0xc0)) -// let noteIndex := add(_3, 0x24) +// let noteIndex := add(add(calldataload(0x04), mul(i, 0xc0)), 0x24) // let k := 0 -// let a := calldataload(add(_3, 0x44)) -// let c := challenge -// let _4 := add(i, 0x01) -// switch eq(_4, n) +// let a := calldataload(add(add(calldataload(0x04), mul(i, 0xc0)), 0x44)) +// let c := mod(calldataload(0x44), 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001) +// let _2 := add(i, 0x01) +// switch eq(_2, n) // case 1 { // k := kn -// if eq(m, n) { k := sub(_2, kn) } +// if eq(calldataload(0x24), n) +// { +// k := sub(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001, kn) +// } // } // case 0 { k := calldataload(noteIndex) } // validateCommitment(noteIndex, k, a) -// switch gt(_4, m) +// switch gt(_2, calldataload(0x24)) // case 1 { -// kn := addmod(kn, sub(_2, k), _2) -// let x := mod(mload(0), _2) -// k := mulmod(k, x, _2) -// a := mulmod(a, x, _2) -// c := mulmod(challenge, x, _2) +// kn := addmod(kn, sub(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001, k), 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001) +// let x := mod(mload(0), 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001) +// k := mulmod(k, x, 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001) +// a := mulmod(a, x, 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001) +// c := mulmod(mod(calldataload(0x44), 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001), x, 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001) // mstore(0, keccak256(0, 0x20)) // } -// case 0 { kn := addmod(kn, k, _2) } -// let _5 := 0x40 -// calldatacopy(0xe0, add(_3, 164), _5) -// calldatacopy(0x20, add(_3, 100), _5) -// let _6 := 0x120 -// mstore(_6, sub(_2, c)) -// let _7 := 0x60 -// mstore(_7, k) +// case 0 { +// kn := addmod(kn, k, 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001) +// } +// calldatacopy(0xe0, add(add(calldataload(0x04), mul(i, 0xc0)), 164), 0x40) +// calldatacopy(0x20, add(add(calldataload(0x04), mul(i, 0xc0)), 100), 0x40) +// mstore(0x120, sub(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001, c)) +// mstore(0x60, k) // mstore(0xc0, a) -// let result := call(gas(), 7, 0, 0xe0, _7, 0x1a0, _5) -// let result_1 := and(result, call(gas(), 7, 0, 0x20, _7, _6, _5)) -// let _8 := 0x160 -// let result_2 := and(result_1, call(gas(), 7, 0, 0x80, _7, _8, _5)) -// let result_3 := and(result_2, call(gas(), 6, 0, _6, 0x80, _8, _5)) -// result := and(result_3, call(gas(), 6, 0, _8, 0x80, b, _5)) -// if eq(i, m) +// let result := call(gas(), 7, 0, 0xe0, 0x60, 0x1a0, 0x40) +// let result_1 := and(result, call(gas(), 7, 0, 0x20, 0x60, 0x120, 0x40)) +// let result_2 := and(result_1, call(gas(), 7, 0, 0x80, 0x60, 0x160, 0x40)) +// let result_3 := and(result_2, call(gas(), 6, 0, 0x120, 0x80, 0x160, 0x40)) +// result := and(result_3, call(gas(), 6, 0, 0x160, 0x80, b, 0x40)) +// if eq(i, calldataload(0x24)) // { // mstore(0x260, mload(0x20)) -// mstore(0x280, mload(_5)) +// mstore(0x280, mload(0x40)) // mstore(0x1e0, mload(0xe0)) // mstore(0x200, sub(0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47, mload(0x100))) // } -// if gt(i, m) +// if gt(i, calldataload(0x24)) // { -// mstore(_7, c) -// let result_4 := and(result, call(gas(), 7, 0, 0x20, _7, 0x220, _5)) -// let result_5 := and(result_4, call(gas(), 6, 0, 0x220, 0x80, 0x260, _5)) -// result := and(result_5, call(gas(), 6, 0, 0x1a0, 0x80, 0x1e0, _5)) +// mstore(0x60, c) +// let _3 := 0x220 +// let result_4 := and(result, call(gas(), 7, 0, 0x20, 0x60, _3, 0x40)) +// let result_5 := and(result_4, call(gas(), 6, 0, _3, 0x80, 0x260, 0x40)) +// result := and(result_5, call(gas(), 6, 0, 0x1a0, 0x80, 0x1e0, 0x40)) // } // if iszero(result) // { // mstore(0, 400) // revert(0, 0x20) // } -// b := add(b, _5) +// b := add(b, 0x40) // } -// if lt(m, n) { validatePairing() } -// if iszero(eq(mod(keccak256(0x2a0, add(b, not(671))), _2), challenge)) +// if lt(calldataload(0x24), n) { validatePairing() } +// if iszero(eq(mod(keccak256(_1, add(b, not(671))), 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001), mod(calldataload(0x44), 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001))) // { // mstore(0, 404) // revert(0, 0x20) diff --git a/test/libyul/yulOptimizerTests/fullSuite/stack_compressor_msize.yul b/test/libyul/yulOptimizerTests/fullSuite/stack_compressor_msize.yul index b417991c2..d670f002f 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/stack_compressor_msize.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/stack_compressor_msize.yul @@ -33,25 +33,30 @@ sstore(0,0) sstore(3,1) } +// ==== +// EVMVersion: >homestead // ---- // step: fullSuite // // { // { -// let _1 := gt(not(gcd(10, 15)), 1) -// let _2 := gcd(10, 15) -// let _3 := not(0) -// let _4 := lt(or(1, add(gcd(10, 15), _3)), 1) -// let _5 := gcd(10, 15) -// let _6 := gcd(10, 15) -// pop(keccak256(gcd(10, 15), or(gt(not(gcd(10, 15)), 1), 1))) -// mstore(lt(or(gt(1, or(or(gt(or(or(or(gt(or(gt(_3, _6), 1), _5), _4), _2), 1), 1), _1), 1)), 1), 1), 1) -// sstore(not(gcd(10, 15)), 1) +// let _1 := 1 +// let _2 := 15 +// let _3 := 10 +// let _4 := gt(not(gcd(_3, _2)), _1) +// let _5 := gcd(_3, _2) +// let _6 := not(0) +// let _7 := lt(or(_1, add(gcd(_3, _2), _6)), _1) +// let _8 := gcd(_3, _2) +// let _9 := gcd(_3, _2) +// pop(keccak256(gcd(_3, _2), or(gt(not(gcd(_3, _2)), _1), _1))) +// mstore(lt(or(gt(_1, or(or(gt(or(or(or(gt(or(gt(_6, _9), _1), _8), _7), _5), _1), _1), _4), _1)), _1), _1), _1) +// sstore(not(gcd(_3, _2)), _1) // sstore(0, 0) -// sstore(2, 1) -// extcodecopy(1, msize(), 1, 1) +// sstore(2, _1) +// extcodecopy(_1, msize(), _1, _1) // sstore(0, 0) -// sstore(3, 1) +// sstore(3, _1) // } // function gcd(_a, _b) -> out // { diff --git a/test/libyul/yulOptimizerTests/stackCompressor/inlineInBlock.yul b/test/libyul/yulOptimizerTests/stackCompressor/inlineInBlock.yul index 4ff056157..382bd201d 100644 --- a/test/libyul/yulOptimizerTests/stackCompressor/inlineInBlock.yul +++ b/test/libyul/yulOptimizerTests/stackCompressor/inlineInBlock.yul @@ -3,6 +3,8 @@ let y := calldataload(calldataload(9)) mstore(y, add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(y, 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1)) } +// ==== +// EVMVersion: =homestead // ---- // step: stackCompressor // diff --git a/test/libyul/yulOptimizerTests/stackCompressor/inlineInFunction.yul b/test/libyul/yulOptimizerTests/stackCompressor/inlineInFunction.yul index f237ea8bb..ed85fe7b8 100644 --- a/test/libyul/yulOptimizerTests/stackCompressor/inlineInFunction.yul +++ b/test/libyul/yulOptimizerTests/stackCompressor/inlineInFunction.yul @@ -5,6 +5,8 @@ mstore(y, add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(y, 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1)) } } +// ==== +// EVMVersion: =homestead // ---- // step: stackCompressor // diff --git a/test/libyul/yulOptimizerTests/stackCompressor/unusedPrunerWithMSize.yul b/test/libyul/yulOptimizerTests/stackCompressor/unusedPrunerWithMSize.yul index 7e3acd9b6..dc10737ad 100644 --- a/test/libyul/yulOptimizerTests/stackCompressor/unusedPrunerWithMSize.yul +++ b/test/libyul/yulOptimizerTests/stackCompressor/unusedPrunerWithMSize.yul @@ -18,6 +18,8 @@ extcodecopy(1, msize(), 1, 1) } } +// ==== +// EVMVersion: =homestead // ---- // step: stackCompressor // diff --git a/test/libyul/yulStackLayout/literal_loop.yul b/test/libyul/yulStackLayout/literal_loop.yul new file mode 100644 index 000000000..841c41062 --- /dev/null +++ b/test/libyul/yulStackLayout/literal_loop.yul @@ -0,0 +1,69 @@ +{ + for {} + add(delegatecall(delegatecall(call(gas(), 0x0, 0x0, 0x0, 0x0, 0x0, 0x0), 0x0, 0x0, 0x0, 0x0, 0x0), 0x0, 0x0, 0x0, 0x0, 0x0),0x0) + {} + {} +} +// ---- +// digraph CFG { +// nodesep=0.7; +// node[shape=box]; +// +// Entry [label="Entry"]; +// Entry -> Block0; +// Block0 [label="\ +// [ ]\l\ +// [ ]\l\ +// "]; +// Block0 -> Block0Exit [arrowhead=none]; +// Block0Exit [label="Jump" shape=oval]; +// Block0Exit -> Block1; +// +// Block1 [label="\ +// [ ]\l\ +// [ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 ]\l\ +// gas\l\ +// [ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 TMP[gas, 0] ]\l\ +// [ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 TMP[gas, 0] ]\l\ +// call\l\ +// [ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 TMP[call, 0] ]\l\ +// [ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 TMP[call, 0] ]\l\ +// delegatecall\l\ +// [ 0x00 0x00 0x00 0x00 0x00 0x00 TMP[delegatecall, 0] ]\l\ +// [ 0x00 0x00 0x00 0x00 0x00 0x00 TMP[delegatecall, 0] ]\l\ +// delegatecall\l\ +// [ 0x00 TMP[delegatecall, 0] ]\l\ +// [ 0x00 TMP[delegatecall, 0] ]\l\ +// add\l\ +// [ TMP[add, 0] ]\l\ +// [ TMP[add, 0] ]\l\ +// "]; +// Block1 -> Block1Exit; +// Block1Exit [label="{ TMP[add, 0]| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1Exit:0 -> Block2; +// Block1Exit:1 -> Block3; +// +// Block2 [label="\ +// [ ]\l\ +// [ ]\l\ +// "]; +// Block2Exit [label="MainExit"]; +// Block2 -> Block2Exit; +// +// Block3 [label="\ +// [ ]\l\ +// [ ]\l\ +// "]; +// Block3 -> Block3Exit [arrowhead=none]; +// Block3Exit [label="Jump" shape=oval]; +// Block3Exit -> Block4; +// +// Block4 [label="\ +// [ ]\l\ +// [ ]\l\ +// "]; +// Block4 -> Block4Exit [arrowhead=none]; +// Block4Exit [label="BackwardsJump" shape=oval]; +// Block4Exit -> Block1; +// +// } From 28ae31655651512575d816dd898e22051db158f0 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Mon, 1 Nov 2021 14:19:33 +0100 Subject: [PATCH 24/69] Named function labels. --- libyul/backends/evm/EVMObjectCompiler.cpp | 10 +- .../evm/OptimizedEVMCodeTransform.cpp | 38 +- .../backends/evm/OptimizedEVMCodeTransform.h | 12 +- .../function_debug_info_via_yul/output | 15 +- .../output.json | 376 +++++++++--------- .../stackReuse/function_call.yul | 10 +- .../stackReuse/functions_multi_return.yul | 28 +- .../stackReuse/reuse_slots_function.yul | 6 +- .../reuse_slots_function_with_gaps.yul | 6 +- test/libyul/evmCodeTransform/stub.yul | 6 +- 10 files changed, 271 insertions(+), 236 deletions(-) diff --git a/libyul/backends/evm/EVMObjectCompiler.cpp b/libyul/backends/evm/EVMObjectCompiler.cpp index c85c1ae92..bede32d17 100644 --- a/libyul/backends/evm/EVMObjectCompiler.cpp +++ b/libyul/backends/evm/EVMObjectCompiler.cpp @@ -65,8 +65,14 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize) yulAssert(_object.code, "No code."); if (_optimize && m_dialect.evmVersion().canOverchargeGasForCall()) { - - auto stackErrors = OptimizedEVMCodeTransform::run(m_assembly, *_object.analysisInfo, *_object.code, m_dialect, context); + auto stackErrors = OptimizedEVMCodeTransform::run( + m_assembly, + *_object.analysisInfo, + *_object.code, + m_dialect, + context, + OptimizedEVMCodeTransform::UseNamedLabels::ForFirstFunctionOfEachName + ); if (!stackErrors.empty()) BOOST_THROW_EXCEPTION(stackErrors.front()); } diff --git a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp index ca57c59d2..08987b565 100644 --- a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp +++ b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp @@ -44,7 +44,7 @@ vector OptimizedEVMCodeTransform::run( Block const& _block, EVMDialect const& _dialect, BuiltinContext& _builtinContext, - bool _useNamedLabelsForFunctions + UseNamedLabels _useNamedLabelsForFunctions ) { std::unique_ptr dfg = ControlFlowGraphBuilder::build(_analysisInfo, _dialect, _block); @@ -170,15 +170,35 @@ void OptimizedEVMCodeTransform::operator()(CFG::Assignment const& _assignment) OptimizedEVMCodeTransform::OptimizedEVMCodeTransform( AbstractAssembly& _assembly, BuiltinContext& _builtinContext, - bool _useNamedLabelsForFunctions, + UseNamedLabels _useNamedLabelsForFunctions, CFG const& _dfg, StackLayout const& _stackLayout ): m_assembly(_assembly), m_builtinContext(_builtinContext), - m_useNamedLabelsForFunctions(_useNamedLabelsForFunctions), m_dfg(_dfg), - m_stackLayout(_stackLayout) + m_stackLayout(_stackLayout), + m_functionLabels([&](){ + map functionLabels; + set assignedFunctionNames; + for (Scope::Function const* function: m_dfg.functions) + { + CFG::FunctionInfo const& functionInfo = m_dfg.functionInfo.at(function); + bool nameAlreadySeen = !assignedFunctionNames.insert(function->name).second; + if (_useNamedLabelsForFunctions == UseNamedLabels::YesAndForceUnique) + yulAssert(!nameAlreadySeen); + bool useNamedLabel = _useNamedLabelsForFunctions != UseNamedLabels::Never && !nameAlreadySeen; + functionLabels[&functionInfo] = useNamedLabel ? + m_assembly.namedLabel( + function->name.str(), + function->arguments.size(), + function->returns.size(), + functionInfo.debugData ? functionInfo.debugData->astID : nullopt + ) : + m_assembly.newLabelId(); + } + return functionLabels; + }()) { } @@ -191,15 +211,7 @@ void OptimizedEVMCodeTransform::assertLayoutCompatibility(Stack const& _currentS AbstractAssembly::LabelID OptimizedEVMCodeTransform::getFunctionLabel(Scope::Function const& _function) { - CFG::FunctionInfo const& functionInfo = m_dfg.functionInfo.at(&_function); - if (!m_functionLabels.count(&functionInfo)) - m_functionLabels[&functionInfo] = m_useNamedLabelsForFunctions ? m_assembly.namedLabel( - functionInfo.function.name.str(), - functionInfo.function.arguments.size(), - functionInfo.function.returns.size(), - {} - ) : m_assembly.newLabelId(); - return m_functionLabels[&functionInfo]; + return m_functionLabels.at(&m_dfg.functionInfo.at(&_function)); } void OptimizedEVMCodeTransform::validateSlot(StackSlot const& _slot, Expression const& _expression) diff --git a/libyul/backends/evm/OptimizedEVMCodeTransform.h b/libyul/backends/evm/OptimizedEVMCodeTransform.h index 48819251a..ed03c1453 100644 --- a/libyul/backends/evm/OptimizedEVMCodeTransform.h +++ b/libyul/backends/evm/OptimizedEVMCodeTransform.h @@ -43,13 +43,17 @@ struct StackLayout; class OptimizedEVMCodeTransform { public: + /// Use named labels for functions 1) Yes and check that the names are unique + /// 2) For none of the functions 3) for the first function of each name. + enum class UseNamedLabels { YesAndForceUnique, Never, ForFirstFunctionOfEachName }; + [[nodiscard]] static std::vector run( AbstractAssembly& _assembly, AsmAnalysisInfo& _analysisInfo, Block const& _block, EVMDialect const& _dialect, BuiltinContext& _builtinContext, - bool _useNamedLabelsForFunctions = false + UseNamedLabels _useNamedLabelsForFunctions ); /// Generate code for the function call @a _call. Only public for using with std::visit. @@ -62,7 +66,7 @@ private: OptimizedEVMCodeTransform( AbstractAssembly& _assembly, BuiltinContext& _builtinContext, - bool _useNamedLabelsForFunctions, + UseNamedLabels _useNamedLabelsForFunctions, CFG const& _dfg, StackLayout const& _stackLayout ); @@ -70,6 +74,7 @@ private: /// Assert that it is valid to transition from @a _currentStack to @a _desiredStack. /// That is @a _currentStack matches each slot in @a _desiredStack that is not a JunkSlot exactly. static void assertLayoutCompatibility(Stack const& _currentStack, Stack const& _desiredStack); + /// @returns The label of the entry point of the given @a _function. /// Creates and stores a new label, if none exists already. AbstractAssembly::LabelID getFunctionLabel(Scope::Function const& _function); @@ -94,13 +99,12 @@ private: AbstractAssembly& m_assembly; BuiltinContext& m_builtinContext; - bool m_useNamedLabelsForFunctions = true; CFG const& m_dfg; StackLayout const& m_stackLayout; Stack m_stack; std::map m_returnLabels; std::map m_blockLabels; - std::map m_functionLabels; + std::map const m_functionLabels; /// Set of blocks already generated. If any of the contained blocks is ever jumped to, m_blockLabels should /// contain a jump label for it. std::set m_generated; diff --git a/test/cmdlineTests/function_debug_info_via_yul/output b/test/cmdlineTests/function_debug_info_via_yul/output index 5af245ce4..495c82d5b 100644 --- a/test/cmdlineTests/function_debug_info_via_yul/output +++ b/test/cmdlineTests/function_debug_info_via_yul/output @@ -4,7 +4,20 @@ "function_debug_info_via_yul/input.sol:C": { "function-debug": {}, - "function-debug-runtime": {} + "function-debug-runtime": + { + "abi_encode_uint256": + { + "parameterSlots": 2, + "returnSlots": 1 + }, + "calldata_array_index_access_uint256_dyn_calldata": + { + "entryPoint": 152, + "parameterSlots": 2, + "returnSlots": 1 + } + } } }, "version": "" diff --git a/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json b/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json index d8877a82b..0c529109a 100644 --- a/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json +++ b/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json @@ -3,7 +3,7 @@ dup1 0x40 mstore - jumpi(tag_5, callvalue) + jumpi(tag_6, callvalue) 0x1f bytecodeSize codesize @@ -25,7 +25,7 @@ dup5 lt or - tag_3 + tag_4 jumpi dup1 dup5 @@ -40,7 +40,7 @@ add sub slt - tag_5 + tag_6 jumpi mload /* \"C\":147:149 42 */ @@ -60,12 +60,12 @@ dup2 assignImmutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") return -tag_5: +tag_6: pop 0x00 dup1 revert -tag_3: +tag_4: pop pop pop @@ -78,11 +78,11 @@ stop sub_0: assembly { /* \"C\":79:428 contract C... */ mstore(0x40, 0x80) - jumpi(tag_1, iszero(lt(calldatasize, 0x04))) + jumpi(tag_8, iszero(lt(calldatasize, 0x04))) 0x00 dup1 revert - tag_1: + tag_8: 0x00 dup1 calldataload @@ -91,35 +91,35 @@ sub_0: assembly { dup1 0x26121ff0 eq - tag_3 + tag_10 jumpi dup1 0x793816ec eq - tag_5 + tag_12 jumpi 0x9942ec6f eq - tag_7 + tag_14 jumpi pop 0x00 dup1 revert - tag_7: - jumpi(tag_9, callvalue) - pop - tag_11 - calldatasize - tag_12 - jump\t// in - tag_11: - tag_13 - /* \"C\":375:378 int */ - tag_14 - tag_15 - jump\t// in tag_14: + jumpi(tag_16, callvalue) + pop + tag_18 + calldatasize + tag_1 + jump\t// in + tag_18: + tag_19 + /* \"C\":375:378 int */ + tag_20 + tag_6 + jump\t// in + tag_20: /* \"C\":79:428 contract C... */ mload(0x40) swap1 @@ -133,23 +133,23 @@ sub_0: assembly { add swap1 jump - tag_13: + tag_19: sub swap1 return - tag_9: + tag_16: dup1 revert - tag_5: + tag_12: pop - jumpi(tag_9, callvalue) - tag_13 + jumpi(tag_16, callvalue) + tag_19 swap1 - tag_20 + tag_24 calldatasize - tag_12 + tag_1 jump\t// in - tag_20: + tag_24: sload mload(0x40) swap1 @@ -163,64 +163,64 @@ sub_0: assembly { add swap1 jump - tag_3: + tag_10: pop - jumpi(tag_9, callvalue) + jumpi(tag_16, callvalue) pop - tag_23 + tag_27 calldatasize - tag_12 + tag_1 jump\t// in - tag_23: - tag_13 + tag_27: + tag_19 /* \"C\":279:298 constVar + immutVar */ - tag_14 + tag_20 /* \"C\":290:298 immutVar */ immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") /* \"C\":279:298 constVar + immutVar */ - tag_26 + tag_4 jump\t// in /* \"C\":79:428 contract C... */ - tag_12: + tag_1: 0x00 swap1 not(0x03) add slt - tag_27 + tag_30 jumpi jump\t// out - tag_27: + tag_30: pop 0x00 dup1 revert /* \"C\":117:119 41 */ - tag_29: + tag_3: pop mstore(0x00, shl(0xe0, 0x4e487b71)) mstore(0x04, 0x11) revert(0x00, 0x24) - tag_26: + tag_4: sub(shl(0xff, 0x01), 0x2a) dup2 sgt 0x01 and - tag_30 + tag_32 jumpi - tag_31: + tag_33: 0x29 add swap1 jump\t// out - tag_30: - tag_32 - tag_29 - jump\t// in tag_32: - jump(tag_31) - tag_33: + tag_34 + tag_3 + jump\t// in + tag_34: + jump(tag_33) + tag_5: 0x00 dup2 slt @@ -233,9 +233,9 @@ sub_0: assembly { dup5 sgt and - tag_34 + tag_35 jumpi - tag_35: + tag_36: shl(0xff, 0x01) dup3 swap1 @@ -243,27 +243,27 @@ sub_0: assembly { dup4 slt and - tag_36 + tag_37 jumpi add swap1 jump\t// out - tag_36: - tag_38 - tag_29 + tag_37: + tag_39 + tag_3 jump\t// in - tag_38: + tag_39: add swap1 jump\t// out - tag_34: - tag_39 - tag_29 + tag_35: + tag_40 + tag_3 jump\t// in - tag_39: - jump(tag_35) + tag_40: + jump(tag_36) /* \"C\":304:341 modifier m()... */ - tag_15: + tag_6: /* \"C\":79:428 contract C... */ 0x00 dup1 @@ -275,10 +275,10 @@ sub_0: assembly { /* \"C\":79:428 contract C... */ dup2 eq - tag_40 + tag_41 jumpi /* \"C\":304:341 modifier m()... */ - tag_41: + tag_42: /* \"C\":79:428 contract C... */ add swap1 @@ -290,7 +290,7 @@ sub_0: assembly { /* \"C\":403:411 this.f() */ extcodesize iszero - tag_42 + tag_43 jumpi /* \"C\":79:428 contract C... */ mload(0x40) @@ -313,38 +313,38 @@ sub_0: assembly { swap2 dup3 iszero - tag_44 + tag_45 jumpi dup1 swap3 - tag_46 + tag_47 jumpi /* \"C\":304:341 modifier m()... */ - tag_47: + tag_48: /* \"C\":392:411 stateVar + this.f() */ pop pop - tag_48 + tag_49 swap1 /* \"C\":392:422 stateVar + this.f() + immutVar */ - tag_49 + tag_50 /* \"C\":392:411 stateVar + this.f() */ swap3 - tag_33 + tag_5 jump\t// in - tag_48: + tag_49: /* \"C\":414:422 immutVar */ immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") /* \"C\":392:422 stateVar + this.f() + immutVar */ swap1 - tag_33 + tag_5 jump\t// in - tag_49: + tag_50: /* \"C\":304:341 modifier m()... */ swap1 jump\t// out /* \"C\":403:411 this.f() */ - tag_46: + tag_47: /* \"C\":79:428 contract C... */ swap1 swap2 @@ -366,18 +366,18 @@ sub_0: assembly { dup4 lt or - tag_50 + tag_51 jumpi pop swap2 /* \"C\":403:411 this.f() */ - tag_52 + tag_53 /* \"C\":392:411 stateVar + this.f() */ - tag_48 + tag_49 /* \"C\":79:428 contract C... */ swap3 /* \"C\":392:422 stateVar + this.f() + immutVar */ - tag_49 + tag_50 /* \"C\":79:428 contract C... */ swap5 0x40 @@ -387,16 +387,16 @@ sub_0: assembly { dup2 add swap1 - tag_53 + tag_7 jump\t// in - tag_52: + tag_53: swap2 dup2 swap4 pop - jump(tag_47) + jump(tag_48) /* \"C\":79:428 contract C... */ - tag_50: + tag_51: shl(0xe0, 0x4e487b71) dup2 mstore @@ -416,7 +416,7 @@ sub_0: assembly { /* \"C\":79:428 contract C... */ revert /* \"C\":403:411 this.f() */ - tag_44: + tag_45: /* \"C\":79:428 contract C... */ swap4 pop @@ -433,20 +433,20 @@ sub_0: assembly { swap1 revert /* \"C\":403:411 this.f() */ - tag_42: + tag_43: /* \"C\":79:428 contract C... */ swap2 pop pop dup1 revert - tag_40: + tag_41: tag_54 - tag_29 + tag_3 jump\t// in tag_54: - jump(tag_41) - tag_53: + jump(tag_42) + tag_7: swap1 dup2 0x20 @@ -472,7 +472,7 @@ sub_0: assembly { dup1 0x40 mstore - jumpi(tag_5, callvalue) + jumpi(tag_6, callvalue) 0x1f bytecodeSize codesize @@ -494,7 +494,7 @@ sub_0: assembly { dup5 lt or - tag_3 + tag_4 jumpi dup1 dup5 @@ -509,14 +509,14 @@ sub_0: assembly { add sub slt - tag_5 + tag_6 jumpi - tag_7 + tag_8 swap1 mload - tag_8 + tag_1 jump\t// in -tag_7: +tag_8: mload(0x40) dataSize(sub_0) swap1 @@ -528,12 +528,12 @@ tag_7: dup2 assignImmutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") return -tag_5: +tag_6: pop 0x00 dup1 revert -tag_3: +tag_4: pop pop pop @@ -542,7 +542,7 @@ tag_3: mstore(0x04, 0x41) revert(0x00, 0x24) /* \"D\":113:164 constructor(int _init2)... */ -tag_8: +tag_1: /* \"C\":147:149 42 */ mstore(0x80, 0x2a) /* \"D\":107:108 3 */ @@ -588,11 +588,11 @@ stop sub_0: assembly { /* \"D\":91:166 contract D is C(3)... */ mstore(0x40, 0x80) - jumpi(tag_1, iszero(lt(calldatasize, 0x04))) + jumpi(tag_8, iszero(lt(calldatasize, 0x04))) 0x00 dup1 revert - tag_1: + tag_8: 0x00 dup1 calldataload @@ -601,35 +601,35 @@ sub_0: assembly { dup1 0x26121ff0 eq - tag_3 + tag_10 jumpi dup1 0x793816ec eq - tag_5 + tag_12 jumpi 0x9942ec6f eq - tag_7 + tag_14 jumpi pop 0x00 dup1 revert - tag_7: - jumpi(tag_9, callvalue) - pop - tag_11 - calldatasize - tag_12 - jump\t// in - tag_11: - tag_13 - /* \"C\":375:378 int */ - tag_14 - tag_15 - jump\t// in tag_14: + jumpi(tag_16, callvalue) + pop + tag_18 + calldatasize + tag_1 + jump\t// in + tag_18: + tag_19 + /* \"C\":375:378 int */ + tag_20 + tag_6 + jump\t// in + tag_20: /* \"D\":91:166 contract D is C(3)... */ mload(0x40) swap1 @@ -643,23 +643,23 @@ sub_0: assembly { add swap1 jump - tag_13: + tag_19: sub swap1 return - tag_9: + tag_16: dup1 revert - tag_5: + tag_12: pop - jumpi(tag_9, callvalue) - tag_13 + jumpi(tag_16, callvalue) + tag_19 swap1 - tag_20 + tag_24 calldatasize - tag_12 + tag_1 jump\t// in - tag_20: + tag_24: sload mload(0x40) swap1 @@ -673,64 +673,64 @@ sub_0: assembly { add swap1 jump - tag_3: + tag_10: pop - jumpi(tag_9, callvalue) + jumpi(tag_16, callvalue) pop - tag_23 + tag_27 calldatasize - tag_12 + tag_1 jump\t// in - tag_23: - tag_13 + tag_27: + tag_19 /* \"C\":279:298 constVar + immutVar */ - tag_14 + tag_20 /* \"C\":290:298 immutVar */ immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") /* \"C\":279:298 constVar + immutVar */ - tag_26 + tag_4 jump\t// in /* \"D\":91:166 contract D is C(3)... */ - tag_12: + tag_1: 0x00 swap1 not(0x03) add slt - tag_27 + tag_30 jumpi jump\t// out - tag_27: + tag_30: pop 0x00 dup1 revert /* \"C\":117:119 41 */ - tag_29: + tag_3: pop mstore(0x00, shl(0xe0, 0x4e487b71)) mstore(0x04, 0x11) revert(0x00, 0x24) - tag_26: + tag_4: sub(shl(0xff, 0x01), 0x2a) dup2 sgt 0x01 and - tag_30 + tag_32 jumpi - tag_31: + tag_33: 0x29 add swap1 jump\t// out - tag_30: - tag_32 - tag_29 - jump\t// in tag_32: - jump(tag_31) - tag_33: + tag_34 + tag_3 + jump\t// in + tag_34: + jump(tag_33) + tag_5: 0x00 dup2 slt @@ -743,9 +743,9 @@ sub_0: assembly { dup5 sgt and - tag_34 + tag_35 jumpi - tag_35: + tag_36: shl(0xff, 0x01) dup3 swap1 @@ -753,27 +753,27 @@ sub_0: assembly { dup4 slt and - tag_36 + tag_37 jumpi add swap1 jump\t// out - tag_36: - tag_38 - tag_29 + tag_37: + tag_39 + tag_3 jump\t// in - tag_38: + tag_39: add swap1 jump\t// out - tag_34: - tag_39 - tag_29 + tag_35: + tag_40 + tag_3 jump\t// in - tag_39: - jump(tag_35) + tag_40: + jump(tag_36) /* \"C\":304:341 modifier m()... */ - tag_15: + tag_6: /* \"D\":91:166 contract D is C(3)... */ 0x00 dup1 @@ -785,10 +785,10 @@ sub_0: assembly { /* \"D\":91:166 contract D is C(3)... */ dup2 eq - tag_40 + tag_41 jumpi /* \"C\":304:341 modifier m()... */ - tag_41: + tag_42: /* \"D\":91:166 contract D is C(3)... */ add swap1 @@ -800,7 +800,7 @@ sub_0: assembly { /* \"C\":403:411 this.f() */ extcodesize iszero - tag_42 + tag_43 jumpi /* \"D\":91:166 contract D is C(3)... */ mload(0x40) @@ -823,38 +823,38 @@ sub_0: assembly { swap2 dup3 iszero - tag_44 + tag_45 jumpi dup1 swap3 - tag_46 + tag_47 jumpi /* \"C\":304:341 modifier m()... */ - tag_47: + tag_48: /* \"C\":392:411 stateVar + this.f() */ pop pop - tag_48 + tag_49 swap1 /* \"C\":392:422 stateVar + this.f() + immutVar */ - tag_49 + tag_50 /* \"C\":392:411 stateVar + this.f() */ swap3 - tag_33 + tag_5 jump\t// in - tag_48: + tag_49: /* \"C\":414:422 immutVar */ immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") /* \"C\":392:422 stateVar + this.f() + immutVar */ swap1 - tag_33 + tag_5 jump\t// in - tag_49: + tag_50: /* \"C\":304:341 modifier m()... */ swap1 jump\t// out /* \"C\":403:411 this.f() */ - tag_46: + tag_47: /* \"D\":91:166 contract D is C(3)... */ swap1 swap2 @@ -876,18 +876,18 @@ sub_0: assembly { dup4 lt or - tag_50 + tag_51 jumpi pop swap2 /* \"C\":403:411 this.f() */ - tag_52 + tag_53 /* \"C\":392:411 stateVar + this.f() */ - tag_48 + tag_49 /* \"D\":91:166 contract D is C(3)... */ swap3 /* \"C\":392:422 stateVar + this.f() + immutVar */ - tag_49 + tag_50 /* \"D\":91:166 contract D is C(3)... */ swap5 0x40 @@ -897,16 +897,16 @@ sub_0: assembly { dup2 add swap1 - tag_53 + tag_7 jump\t// in - tag_52: + tag_53: swap2 dup2 swap4 pop - jump(tag_47) + jump(tag_48) /* \"D\":91:166 contract D is C(3)... */ - tag_50: + tag_51: shl(0xe0, 0x4e487b71) dup2 mstore @@ -926,7 +926,7 @@ sub_0: assembly { /* \"D\":91:166 contract D is C(3)... */ revert /* \"C\":403:411 this.f() */ - tag_44: + tag_45: /* \"D\":91:166 contract D is C(3)... */ swap4 pop @@ -943,20 +943,20 @@ sub_0: assembly { swap1 revert /* \"C\":403:411 this.f() */ - tag_42: + tag_43: /* \"D\":91:166 contract D is C(3)... */ swap2 pop pop dup1 revert - tag_40: + tag_41: tag_54 - tag_29 + tag_3 jump\t// in tag_54: - jump(tag_41) - tag_53: + jump(tag_42) + tag_7: swap1 dup2 0x20 diff --git a/test/libyul/evmCodeTransform/stackReuse/function_call.yul b/test/libyul/evmCodeTransform/stackReuse/function_call.yul index 1abc8d8af..507b35441 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_call.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_call.yul @@ -7,15 +7,15 @@ // stackOptimization: true // ---- // /* "":15:22 */ -// tag_1 +// tag_2 // /* "":20:21 */ // 0x02 // /* "":17:18 */ // 0x01 // /* "":15:22 */ -// tag_2 +// tag_1 // jump // in -// tag_1: +// tag_2: // /* "":62:69 */ // pop // tag_3 @@ -24,13 +24,13 @@ // /* "":64:65 */ // 0x03 // /* "":62:69 */ -// tag_2 +// tag_1 // jump // in // tag_3: // /* "":0:71 */ // stop // /* "":27:52 */ -// tag_2: +// tag_1: // pop // pop // /* "":47:48 */ diff --git a/test/libyul/evmCodeTransform/stackReuse/functions_multi_return.yul b/test/libyul/evmCodeTransform/stackReuse/functions_multi_return.yul index df8b96184..1ce02483d 100644 --- a/test/libyul/evmCodeTransform/stackReuse/functions_multi_return.yul +++ b/test/libyul/evmCodeTransform/stackReuse/functions_multi_return.yul @@ -11,37 +11,37 @@ // stackOptimization: true // ---- // /* "":74:81 */ -// tag_1 +// tag_3 // /* "":79:80 */ // 0x02 // /* "":76:77 */ // 0x01 // /* "":74:81 */ -// tag_2 +// tag_1 // jump // in -// tag_1: +// tag_3: // /* "":91:98 */ // pop -// tag_3 +// tag_4 // /* "":96:97 */ // 0x04 // /* "":93:94 */ // 0x03 // /* "":91:98 */ -// tag_2 -// jump // in -// tag_3: -// /* "":115:118 */ -// pop -// tag_4 -// tag_5 +// tag_1 // jump // in // tag_4: +// /* "":115:118 */ +// pop +// tag_5 +// tag_2 +// jump // in +// tag_5: // /* "":131:134 */ // pop // pop // tag_6 -// tag_5 +// tag_2 // jump // in // tag_6: // /* "":139:154 */ @@ -52,7 +52,7 @@ // /* "":0:156 */ // stop // /* "":6:31 */ -// tag_2: +// tag_1: // pop // pop // /* "":26:27 */ @@ -61,7 +61,7 @@ // swap1 // jump // out // /* "":36:60 */ -// tag_5: +// tag_2: // /* "":55:56 */ // 0x00 // /* "":52:53 */ diff --git a/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function.yul b/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function.yul index a7a8b1a02..13e3065cc 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function.yul @@ -6,10 +6,10 @@ // stackOptimization: true // ---- // /* "":58:61 */ -// tag_1 // tag_2 +// tag_1 // jump // in -// tag_1: +// tag_2: // /* "":62:73 */ // pop // swap2 @@ -29,7 +29,7 @@ // /* "":0:115 */ // stop // /* "":6:35 */ -// tag_2: +// tag_1: // /* "":25:26 */ // 0x00 // /* "":28:29 */ diff --git a/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function_with_gaps.yul b/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function_with_gaps.yul index 888bccf7d..f1cde362a 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function_with_gaps.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function_with_gaps.yul @@ -19,10 +19,10 @@ // swap2 // mstore // /* "":207:210 */ -// tag_1 // tag_2 +// tag_1 // jump // in -// tag_1: +// tag_2: // /* "":211:224 */ // swap4 // swap1 @@ -35,7 +35,7 @@ // /* "":0:239 */ // stop // /* "":155:184 */ -// tag_2: +// tag_1: // /* "":174:175 */ // 0x00 // /* "":177:178 */ diff --git a/test/libyul/evmCodeTransform/stub.yul b/test/libyul/evmCodeTransform/stub.yul index a11cad44c..ef7cd668c 100644 --- a/test/libyul/evmCodeTransform/stub.yul +++ b/test/libyul/evmCodeTransform/stub.yul @@ -21,14 +21,14 @@ // stackOptimization: true // ---- // /* "":14:21 */ -// tag_1 // tag_2 +// tag_1 // jump // in -// tag_1: +// tag_2: // /* "":0:460 */ // stop // /* "":34:458 */ -// tag_2: +// tag_1: // /* "":108:109 */ // 0x00 // /* "":95:110 */ From e9708105a40845083a8ee83e03848975ea6dfb28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 21 Oct 2021 17:11:18 +0200 Subject: [PATCH 25/69] CI: Remove superfluous/unused test_ dicts --- .circleci/config.yml | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 00c7223d5..b53999f2a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -219,14 +219,6 @@ defaults: parallelism: 6 <<: *steps_soltest_all - - test_asan: &test_asan - <<: *test_ubuntu2004 - <<: *steps_soltest - - - test_ubuntu2004_clang_cli: &test_ubuntu2004_clang_cli - docker: - - image: << pipeline.parameters.ubuntu-2004-clang-docker-image >> - <<: *steps_cmdline_tests # -------------------------------------------------------------------------- # Workflow Templates @@ -806,7 +798,7 @@ jobs: <<: *steps_cmdline_tests t_ubu_asan: - <<: *test_asan + <<: *test_ubuntu2004 environment: EVM: << pipeline.parameters.evm-version >> OPTIMIZE: 0 From 9aafbf1092e434e4ed2491db3e1babb7cf50df99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 21 Oct 2021 17:12:03 +0200 Subject: [PATCH 26/69] CI: Replace `test_` dicts with `base_` ones and make their steps explicit --- .circleci/config.yml | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b53999f2a..82c860bb7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -170,7 +170,7 @@ defaults: destination: test_results/ # -------------------------------------------------------------------------- - # Tests Templates + # Step Templates # store_test_results helper - store_test_results: &store_test_results @@ -181,6 +181,9 @@ defaults: - checkout - attach_workspace: at: build + # NOTE: Different build jobs produce different soltest executables (release/debug, + # clang/gcc, windows/linux/macos, etc.). The executable used by these steps comes from the + # attached workspace and we only see the items added to the workspace by jobs we depend on. - run: *run_soltest - store_test_results: *store_test_results - store_artifacts: *artifacts_test_results @@ -203,22 +206,20 @@ defaults: - store_test_results: *store_test_results - store_artifacts: *artifacts_test_results - - test_ubuntu1604_clang: &test_ubuntu1604_clang + # -------------------------------------------------------------------------- + # Base Image Templates + + - base_ubuntu1604_clang: &base_ubuntu1604_clang docker: - image: << pipeline.parameters.ubuntu-1604-clang-ossfuzz-docker-image >> - <<: *steps_soltest - - test_ubuntu2004_clang: &test_ubuntu2004_clang + - base_ubuntu2004_clang: &base_ubuntu2004_clang docker: - image: << pipeline.parameters.ubuntu-2004-clang-docker-image >> - <<: *steps_soltest - - test_ubuntu2004: &test_ubuntu2004 + - base_ubuntu2004: &base_ubuntu2004 docker: - image: << pipeline.parameters.ubuntu-2004-docker-image >> - parallelism: 6 - <<: *steps_soltest_all - # -------------------------------------------------------------------------- # Workflow Templates @@ -551,7 +552,8 @@ jobs: - persist_to_workspace: *artifacts_executables t_ubu_codecov: - <<: *test_ubuntu2004 + <<: *base_ubuntu2004 + parallelism: 6 environment: EVM: << pipeline.parameters.evm-version >> OPTIMIZE: 1 @@ -598,7 +600,7 @@ jobs: - persist_to_workspace: *artifacts_executables_ossfuzz t_ubu_ossfuzz: &t_ubu_ossfuzz - <<: *test_ubuntu1604_clang + <<: *base_ubuntu1604_clang steps: - checkout - attach_workspace: @@ -739,7 +741,9 @@ jobs: destination: docs-html t_ubu_soltest: &t_ubu_soltest - <<: *test_ubuntu2004 + <<: *base_ubuntu2004 + parallelism: 6 + <<: *steps_soltest_all t_archlinux_soltest: &t_archlinux_soltest docker: @@ -772,12 +776,15 @@ jobs: t_ubu_clang_soltest: &t_ubu_clang_soltest - <<: *test_ubuntu2004_clang + <<: *base_ubuntu2004_clang environment: EVM: << pipeline.parameters.evm-version >> OPTIMIZE: 0 + <<: *steps_soltest t_ubu_release_soltest: &t_ubu_release_soltest + # NOTE: This definition is identical to t_ubu_soltest_all but in the workflow we make it depend on + # a different job (b_ubu_release) so the workspace it attaches contains a different executable. <<: *t_ubu_soltest t_ubu_cli: &t_ubu_cli @@ -798,20 +805,23 @@ jobs: <<: *steps_cmdline_tests t_ubu_asan: - <<: *test_ubuntu2004 + <<: *base_ubuntu2004 + parallelism: 6 environment: EVM: << pipeline.parameters.evm-version >> OPTIMIZE: 0 SOLTEST_FLAGS: --no-smt 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 + <<: *steps_soltest t_ubu_asan_clang: - <<: *test_ubuntu2004_clang + <<: *base_ubuntu2004_clang environment: EVM: << pipeline.parameters.evm-version >> OPTIMIZE: 0 SOLTEST_FLAGS: --no-smt 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 + <<: *steps_soltest t_ubu_ubsan_clang: environment: From 9c96234724d40c760c6708c44d8ff5150dd06d24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 21 Oct 2021 17:37:05 +0200 Subject: [PATCH 27/69] CI: Define a `base_` dict for every image and set default values for some env variables there --- .circleci/config.yml | 267 ++++++++++++++++++++++--------------------- 1 file changed, 135 insertions(+), 132 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 82c860bb7..97b61107f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -212,14 +212,93 @@ defaults: - base_ubuntu1604_clang: &base_ubuntu1604_clang docker: - image: << pipeline.parameters.ubuntu-1604-clang-ossfuzz-docker-image >> + environment: + TERM: xterm - base_ubuntu2004_clang: &base_ubuntu2004_clang docker: - image: << pipeline.parameters.ubuntu-2004-clang-docker-image >> + environment: + TERM: xterm + CC: clang + CXX: clang++ + MAKEFLAGS: -j 3 + + - base_ubuntu2004_clang_xlarge: &base_ubuntu2004_clang_xlarge + <<: *base_ubuntu2004_clang + resource_class: xlarge + environment: + TERM: xterm + CC: clang + CXX: clang++ + MAKEFLAGS: -j 10 - base_ubuntu2004: &base_ubuntu2004 docker: - image: << pipeline.parameters.ubuntu-2004-docker-image >> + environment: + TERM: xterm + + - base_ubuntu2004_xlarge: &base_ubuntu2004_xlarge + <<: *base_ubuntu2004 + resource_class: xlarge + environment: + TERM: xterm + MAKEFLAGS: -j 10 + + - base_buildpack_focal: &base_buildpack_focal + docker: + - image: buildpack-deps:focal + environment: + TERM: xterm + + - base_buildpack_latest: &base_buildpack_latest + docker: + - image: buildpack-deps:latest + environment: + TERM: xterm + + - base_archlinux: &base_archlinux + docker: + - image: archlinux:base + environment: + TERM: xterm + + - base_win_powershell: &base_win_powershell + executor: + name: win/default + shell: powershell.exe + + - base_win_cmd: &base_win_cmd + executor: + name: win/default + shell: cmd.exe + + - base_osx: &base_osx + macos: + xcode: "11.0.0" + environment: + TERM: xterm + + - base_ems_xlarge: &base_ems_xlarge + docker: + - image: << pipeline.parameters.emscripten-docker-image >> + resource_class: xlarge + environment: + TERM: xterm + MAKEFLAGS: -j 10 + + - base_python: &base_python + docker: + - image: circleci/python:3.6 + environment: + TERM: xterm + + - base_node_latest: &base_node_latest + docker: + - image: circleci/node + environment: + TERM: xterm # -------------------------------------------------------------------------- # Workflow Templates @@ -303,10 +382,7 @@ defaults: jobs: chk_spelling: - docker: - - image: circleci/python:3.6 - environment: - TERM: xterm + <<: *base_python steps: - checkout - attach_workspace: @@ -320,10 +396,7 @@ jobs: command: ~/.local/bin/codespell -S "*.enc,.git,Dockerfile*" -I ./scripts/codespell_whitelist.txt chk_docs_examples: - docker: - - image: circleci/node - environment: - TERM: xterm + <<: *base_node_latest steps: - checkout - attach_workspace: @@ -336,8 +409,7 @@ jobs: command: ./test/docsCodeStyle.sh chk_coding_style: - docker: - - image: buildpack-deps:focal + <<: *base_buildpack_focal steps: - checkout - run: @@ -354,8 +426,7 @@ jobs: command: ./scripts/check_symlinks.sh chk_errorcodes: - docker: - - image: circleci/python:3.6 + <<: *base_python steps: - checkout - run: @@ -363,8 +434,7 @@ jobs: command: ./scripts/error_codes.py --check chk_pylint: - docker: - - image: buildpack-deps:focal + <<: *base_buildpack_focal steps: - checkout - run: @@ -379,8 +449,7 @@ jobs: command: ./scripts/pylint_all.py chk_antlr_grammar: - docker: - - image: buildpack-deps:focal + <<: *base_buildpack_focal steps: - checkout - run: @@ -391,10 +460,7 @@ jobs: command: ./scripts/test_antlr_grammar.sh chk_buglist: - docker: - - image: circleci/node - environment: - TERM: xterm + <<: *base_node_latest steps: - checkout - run: @@ -408,10 +474,7 @@ jobs: command: ./test/buglistTests.js chk_proofs: - docker: - - image: buildpack-deps:latest - environment: - TERM: xterm + <<: *base_buildpack_latest steps: - checkout - run: @@ -423,17 +486,13 @@ jobs: - run: *run_proofs chk_docs_pragma_min_version: - docker: - - image: << pipeline.parameters.ubuntu-2004-docker-image >> - environment: - TERM: xterm + <<: *base_ubuntu2004 steps: - checkout - run: *run_docs_pragma_min_version t_pyscripts_ubu: - docker: - - image: << pipeline.parameters.ubuntu-2004-docker-image >> + <<: *base_ubuntu2004 steps: - checkout - run: @@ -441,9 +500,7 @@ jobs: command: python3 test/pyscriptTests.py t_pyscripts_win: - executor: - name: win/default - shell: powershell.exe + <<: *base_win_powershell steps: - run: git config --global core.autocrlf false - checkout @@ -452,11 +509,7 @@ jobs: command: python.exe test/pyscriptTests.py b_ubu: &b_ubu - resource_class: xlarge - docker: - - image: << pipeline.parameters.ubuntu-2004-docker-image >> - environment: - MAKEFLAGS: -j 10 + <<: *base_ubuntu2004_xlarge steps: - checkout - run: *run_build @@ -467,7 +520,7 @@ jobs: # x64 ASAN build, for testing for memory related bugs b_ubu_asan: &b_ubu_asan - <<: *b_ubu + <<: *base_ubuntu2004_xlarge environment: CMAKE_OPTIONS: -DSANITIZE=address MAKEFLAGS: -j 10 @@ -479,13 +532,7 @@ jobs: - persist_to_workspace: *artifacts_executables b_ubu_clang: &b_ubu_clang - resource_class: xlarge - docker: - - image: << pipeline.parameters.ubuntu-2004-clang-docker-image >> - environment: - CC: clang - CXX: clang++ - MAKEFLAGS: -j 10 + <<: *base_ubuntu2004_clang_xlarge steps: - checkout - run: *run_build @@ -493,8 +540,7 @@ jobs: - persist_to_workspace: *artifacts_executables b_ubu_asan_clang: &b_ubu_asan_clang - docker: - - image: << pipeline.parameters.ubuntu-2004-clang-docker-image >> + <<: *base_ubuntu2004_clang environment: CC: clang CXX: clang++ @@ -507,8 +553,7 @@ jobs: - persist_to_workspace: *artifacts_executables b_ubu_ubsan_clang: &b_ubu_ubsan_clang - docker: - - image: << pipeline.parameters.ubuntu-2004-clang-docker-image >> + <<: *base_ubuntu2004_clang environment: CC: clang CXX: clang++ @@ -528,7 +573,7 @@ jobs: MAKEFLAGS: -j 10 b_ubu_static: - <<: *b_ubu + <<: *base_ubuntu2004_xlarge environment: MAKEFLAGS: -j 10 CMAKE_OPTIONS: -DCMAKE_BUILD_TYPE=Release -DUSE_Z3_DLOPEN=ON -DUSE_CVC4=OFF -DSOLC_STATIC_STDLIBS=ON @@ -541,7 +586,7 @@ jobs: - store_artifacts: *artifacts_solc b_ubu_codecov: - <<: *b_ubu + <<: *base_ubuntu2004_xlarge environment: COVERAGE: ON CMAKE_BUILD_TYPE: Debug @@ -576,7 +621,7 @@ jobs: # Builds in C++20 mode and uses debug build in order to speed up. # Do *NOT* store any artifacts or workspace as we don't run tests on this build. b_ubu_cxx20: - <<: *b_ubu + <<: *base_ubuntu2004_xlarge environment: CMAKE_BUILD_TYPE: Debug CMAKE_OPTIONS: -DCMAKE_CXX_STANDARD=20 -DUSE_CVC4=OFF @@ -586,13 +631,7 @@ jobs: - run: *run_build b_ubu_ossfuzz: &b_ubu_ossfuzz - docker: - - image: << pipeline.parameters.ubuntu-1604-clang-ossfuzz-docker-image >> - environment: - CC: clang - CXX: clang++ - TERM: xterm - MAKEFLAGS: -j 3 + <<: *base_ubuntu1604_clang steps: - checkout - run: *setup_prerelease_commit_hash @@ -617,8 +656,7 @@ jobs: - store_artifacts: *artifacts_test_results b_archlinux: - docker: - - image: archlinux:base + <<: *base_archlinux environment: TERM: xterm MAKEFLAGS: -j 3 @@ -633,8 +671,7 @@ jobs: - persist_to_workspace: *artifacts_executables b_osx: - macos: - xcode: "11.0.0" + <<: *base_osx environment: TERM: xterm CMAKE_BUILD_TYPE: Release @@ -670,8 +707,7 @@ jobs: - build/test/tools/solfuzzer t_osx_soltest: - macos: - xcode: "11.0.0" + <<: *base_osx environment: EVM: << pipeline.parameters.evm-version >> OPTIMIZE: 0 @@ -688,10 +724,7 @@ jobs: - store_artifacts: *artifacts_test_results t_osx_cli: - macos: - xcode: "11.0.0" - environment: - TERM: xterm + <<: *base_osx steps: - checkout - restore_cache: @@ -703,12 +736,7 @@ jobs: - store_artifacts: *artifacts_test_results b_ems: - resource_class: xlarge - docker: - - image: << pipeline.parameters.emscripten-docker-image >> - environment: - MAKEFLAGS: -j 10 - TERM: xterm + <<: *base_ems_xlarge steps: - checkout - run: @@ -728,8 +756,7 @@ jobs: - version.txt b_docs: - docker: - - image: << pipeline.parameters.ubuntu-2004-docker-image >> + <<: *base_ubuntu2004 steps: - checkout - run: *setup_prerelease_commit_hash @@ -746,27 +773,25 @@ jobs: <<: *steps_soltest_all t_archlinux_soltest: &t_archlinux_soltest - docker: - - image: archlinux:base - environment: - EVM: << pipeline.parameters.evm-version >> - OPTIMIZE: 0 - TERM: xterm - # For Archlinux we do not have prebuilt docker images and we would need to build evmone from source, - # thus we forgo semantics tests to speed things up. - SOLTEST_FLAGS: --no-semantic-tests - steps: - - run: - name: Install runtime dependencies - command: | - pacman --noconfirm -Syu --noprogressbar --needed base-devel boost cmake z3 cvc4 git openssh tar - - when: - condition: true - <<: *steps_soltest + <<: *base_archlinux + environment: + EVM: << pipeline.parameters.evm-version >> + OPTIMIZE: 0 + TERM: xterm + # For Archlinux we do not have prebuilt docker images and we would need to build evmone from source, + # thus we forgo semantics tests to speed things up. + SOLTEST_FLAGS: --no-semantic-tests + steps: + - run: + name: Install runtime dependencies + command: | + pacman --noconfirm -Syu --noprogressbar --needed base-devel boost cmake z3 cvc4 git openssh tar + - when: + condition: true + <<: *steps_soltest t_ubu_soltest_enforce_yul: &t_ubu_soltest_enforce_yul - docker: - - image: << pipeline.parameters.ubuntu-2004-docker-image >> + <<: *base_ubuntu2004 environment: EVM: << pipeline.parameters.evm-version >> SOLTEST_FLAGS: --enforce-via-yul @@ -774,7 +799,6 @@ jobs: TERM: xterm <<: *steps_soltest - t_ubu_clang_soltest: &t_ubu_clang_soltest <<: *base_ubuntu2004_clang environment: @@ -788,17 +812,14 @@ jobs: <<: *t_ubu_soltest t_ubu_cli: &t_ubu_cli - docker: - - image: << pipeline.parameters.ubuntu-2004-docker-image >> - environment: - TERM: xterm + <<: *base_ubuntu2004 <<: *steps_cmdline_tests t_ubu_release_cli: &t_ubu_release_cli <<: *t_ubu_cli t_ubu_asan_cli: - <<: *t_ubu_cli + <<: *base_ubuntu2004 environment: TERM: xterm 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 @@ -824,10 +845,9 @@ jobs: <<: *steps_soltest t_ubu_ubsan_clang: + <<: *base_ubuntu2004_clang environment: EVM: << pipeline.parameters.evm-version >> - docker: - - image: << pipeline.parameters.ubuntu-2004-clang-docker-image >> steps: - when: condition: true @@ -835,8 +855,7 @@ jobs: - gitter_notify_failure t_ubu_ubsan_clang_cli: - docker: - - image: << pipeline.parameters.ubuntu-2004-clang-docker-image >> + <<: *base_ubuntu2004_clang steps: - when: condition: true @@ -844,10 +863,7 @@ jobs: - gitter_notify_failure t_ems_solcjs: - docker: - - image: << pipeline.parameters.ubuntu-2004-docker-image >> - environment: - TERM: xterm + <<: *base_ubuntu2004 steps: - checkout - attach_workspace: @@ -866,8 +882,7 @@ jobs: test/externalTests/solc-js/solc-js.sh /tmp/workspace/soljson.js $(cat /tmp/workspace/version.txt) t_ems_ext_hardhat: - docker: - - image: circleci/node + <<: *base_node_latest environment: TERM: xterm HARDHAT_TESTS_SOLC_PATH: /tmp/workspace/soljson.js @@ -929,9 +944,7 @@ jobs: - gitter_notify_success b_win: &b_win - executor: - name: win/default - shell: powershell.exe + <<: *base_win_powershell steps: # NOTE: Not disabling git's core.autocrlf here because we want to build using the typical Windows config. - checkout @@ -966,9 +979,7 @@ jobs: FORCE_RELEASE: ON t_win: &t_win - executor: - name: win/default - shell: powershell.exe + <<: *base_win_powershell steps: # NOTE: Git's default core.autocrlf is fine for running soltest. We get additional coverage # for files using CRLF that way. @@ -988,8 +999,7 @@ jobs: <<: *t_win b_bytecode_ubu: - docker: - - image: << pipeline.parameters.ubuntu-2004-docker-image >> + <<: *base_ubuntu2004 steps: - checkout - attach_workspace: @@ -1009,10 +1019,7 @@ jobs: - bytecode-report-ubuntu-cli.txt b_bytecode_osx: - macos: - xcode: "11.0.0" - environment: - TERM: xterm + <<: *base_osx steps: - checkout - attach_workspace: @@ -1032,9 +1039,7 @@ jobs: - bytecode-report-osx-cli.txt b_bytecode_win: - executor: - name: win/default - shell: cmd.exe + <<: *base_win_cmd steps: # NOTE: For bytecode generation we need the input files to be byte-for-byte identical on all # platforms so line ending conversions must absolutely be disabled. @@ -1057,8 +1062,7 @@ jobs: - bytecode-report-windows-cli.txt b_bytecode_ems: - docker: - - image: circleci/node:16 + <<: *base_node_latest environment: SOLC_EMSCRIPTEN: "On" steps: @@ -1074,8 +1078,7 @@ jobs: - bytecode-report-emscripten.txt t_bytecode_compare: - docker: - - image: << pipeline.parameters.ubuntu-2004-docker-image >> + <<: *base_ubuntu2004 environment: REPORT_FILES: | bytecode-report-emscripten.txt From c76a8a738dc0274f4623deccf0b2453dbac1b772 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 21 Oct 2021 17:56:50 +0200 Subject: [PATCH 28/69] CI: Tweak some job names to better reflect what they run --- .circleci/config.yml | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 97b61107f..e2ba6e2d0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -491,7 +491,7 @@ jobs: - checkout - run: *run_docs_pragma_min_version - t_pyscripts_ubu: + t_ubu_pyscripts: <<: *base_ubuntu2004 steps: - checkout @@ -499,7 +499,7 @@ jobs: name: Python unit tests command: python3 test/pyscriptTests.py - t_pyscripts_win: + t_win_pyscripts: <<: *base_win_powershell steps: - run: git config --global core.autocrlf false @@ -767,7 +767,7 @@ jobs: path: docs/_build/html/ destination: docs-html - t_ubu_soltest: &t_ubu_soltest + t_ubu_soltest_all: &t_ubu_soltest_all <<: *base_ubuntu2004 parallelism: 6 <<: *steps_soltest_all @@ -806,10 +806,10 @@ jobs: OPTIMIZE: 0 <<: *steps_soltest - t_ubu_release_soltest: &t_ubu_release_soltest + t_ubu_release_soltest_all: &t_ubu_release_soltest_all # NOTE: This definition is identical to t_ubu_soltest_all but in the workflow we make it depend on # a different job (b_ubu_release) so the workspace it attaches contains a different executable. - <<: *t_ubu_soltest + <<: *t_ubu_soltest_all t_ubu_cli: &t_ubu_cli <<: *base_ubuntu2004 @@ -825,7 +825,7 @@ jobs: 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 <<: *steps_cmdline_tests - t_ubu_asan: + t_ubu_asan_soltest: <<: *base_ubuntu2004 parallelism: 6 environment: @@ -835,7 +835,7 @@ jobs: 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 <<: *steps_soltest - t_ubu_asan_clang: + t_ubu_asan_clang_soltest: <<: *base_ubuntu2004_clang environment: EVM: << pipeline.parameters.evm-version >> @@ -844,7 +844,7 @@ jobs: 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 <<: *steps_soltest - t_ubu_ubsan_clang: + t_ubu_ubsan_clang_soltest: <<: *base_ubuntu2004_clang environment: EVM: << pipeline.parameters.evm-version >> @@ -978,7 +978,7 @@ jobs: environment: FORCE_RELEASE: ON - t_win: &t_win + t_win_soltest: &t_win_soltest <<: *base_win_powershell steps: # NOTE: Git's default core.autocrlf is fine for running soltest. We get additional coverage @@ -995,8 +995,8 @@ jobs: - store_test_results: *store_test_results - store_artifacts: *artifacts_test_results - t_win_release: - <<: *t_win + t_win_release_soltest: + <<: *t_win_soltest b_bytecode_ubu: <<: *base_ubuntu2004 @@ -1128,8 +1128,8 @@ workflows: - chk_errorcodes: *workflow_trigger_on_tags - chk_antlr_grammar: *workflow_trigger_on_tags - chk_docs_pragma_min_version: *workflow_trigger_on_tags - - t_pyscripts_ubu: *workflow_trigger_on_tags - - t_pyscripts_win: *workflow_trigger_on_tags + - t_ubu_pyscripts: *workflow_trigger_on_tags + - t_win_pyscripts: *workflow_trigger_on_tags # build-only - b_docs: *workflow_trigger_on_tags @@ -1151,7 +1151,7 @@ workflows: # Ubuntu build and tests - b_ubu: *workflow_trigger_on_tags - t_ubu_cli: *workflow_ubuntu2004 - - t_ubu_soltest: *workflow_ubuntu2004 + - t_ubu_soltest_all: *workflow_ubuntu2004 - t_ubu_soltest_enforce_yul: *workflow_ubuntu2004 - b_ubu_clang: *workflow_trigger_on_tags - t_ubu_clang_soltest: *workflow_ubuntu2004_clang @@ -1159,7 +1159,7 @@ workflows: # Ubuntu fake release build and tests - b_ubu_release: *workflow_trigger_on_tags - t_ubu_release_cli: *workflow_ubuntu2004_release - - t_ubu_release_soltest: *workflow_ubuntu2004_release + - t_ubu_release_soltest_all: *workflow_ubuntu2004_release # Emscripten build and tests that take 15 minutes or less - b_ems: *workflow_trigger_on_tags @@ -1222,8 +1222,8 @@ workflows: # Windows build and tests - b_win: *workflow_trigger_on_tags - b_win_release: *workflow_trigger_on_tags - - t_win: *workflow_win - - t_win_release: *workflow_win_release + - t_win_soltest: *workflow_win + - t_win_release_soltest: *workflow_win_release # Bytecode comparison: - b_bytecode_ubu: @@ -1267,13 +1267,13 @@ workflows: # ASan build and tests - b_ubu_asan: *workflow_trigger_on_tags - b_ubu_asan_clang: *workflow_trigger_on_tags - - t_ubu_asan: *workflow_ubuntu2004_asan - - t_ubu_asan_clang: *workflow_ubuntu2004_asan_clang + - t_ubu_asan_soltest: *workflow_ubuntu2004_asan + - t_ubu_asan_clang_soltest: *workflow_ubuntu2004_asan_clang - t_ubu_asan_cli: *workflow_ubuntu2004_asan # UBSan build and tests - b_ubu_ubsan_clang: *workflow_trigger_on_tags - - t_ubu_ubsan_clang: *workflow_ubuntu2004_ubsan_clang + - t_ubu_ubsan_clang_soltest: *workflow_ubuntu2004_ubsan_clang - t_ubu_ubsan_clang_cli: *workflow_ubuntu2004_ubsan_clang # Emscripten build and tests that take more than 15 minutes to execute From dff280cadc6ec83e39e1bdabc2673d56ab528f95 Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Wed, 3 Nov 2021 15:40:54 +0100 Subject: [PATCH 29/69] Fix ICE in CHC when using gas in the function options --- Changelog.md | 1 + libsolidity/formal/CHC.cpp | 4 ++-- .../external_calls/external_call_with_gas_1.sol | 9 +++++++++ 3 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 test/libsolidity/smtCheckerTests/external_calls/external_call_with_gas_1.sol diff --git a/Changelog.md b/Changelog.md index c724693ee..e17420b67 100644 --- a/Changelog.md +++ b/Changelog.md @@ -23,6 +23,7 @@ Bugfixes: * Commandline Interface: Report output selection options unsupported by the selected input mode instead of ignoring them. * 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. * SMTChecker: Fix internal error in magic type access (``block``, ``msg``, ``tx``). + * SMTChecker: Fix internal error in the CHC engine when passing gas in the function options. * TypeChecker: Fix internal error when using user defined value types in public library functions. * TypeChecker: Fix internal error when using arrays and structs with user defined value types before declaration. * TypeChecker: Improved error message for constant variables with (nested) mapping types. diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index c0a92264e..76a5ded99 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -791,8 +791,8 @@ void CHC::externalFunctionCall(FunctionCall const& _funCall) valueIndex = i; break; } - solAssert(valueIndex, ""); - state().addBalance(state().thisAddress(), 0 - expr(*callOptions->options().at(*valueIndex))); + if (valueIndex) + state().addBalance(state().thisAddress(), 0 - expr(*callOptions->options().at(*valueIndex))); } auto preCallState = vector{state().state()} + currentStateVariables(); diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_call_with_gas_1.sol b/test/libsolidity/smtCheckerTests/external_calls/external_call_with_gas_1.sol new file mode 100644 index 000000000..86cbbe9b5 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/external_calls/external_call_with_gas_1.sol @@ -0,0 +1,9 @@ +library L { + function f() public view { + (bool success, ) = address(10).staticcall{gas: 3}(""); + require(success); + } +} +// ==== +// SMTEngine: all +// ---- From 45b87d41f7aabcde14ec87b96ccef61bf6622f4d Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Wed, 3 Nov 2021 16:38:36 +0100 Subject: [PATCH 30/69] Add missing changelog entry. --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index c724693ee..f92e20c7e 100644 --- a/Changelog.md +++ b/Changelog.md @@ -12,6 +12,7 @@ Compiler Features: * 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``. * Standard JSON: Accept nested brackets in step sequences passed to ``settings.optimizer.details.yulDetails.optimizerSteps``. * 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. + * Yul EVM Code Transform: Switch to new optimized code transform when compiling via Yul with enabled optimizer. * Yul Optimizer: Take control-flow side-effects of user-defined functions into account in various optimizer steps. From 0cbb297c7bf7a81b54ec7c429e65367a78e901d6 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Tue, 2 Nov 2021 11:07:52 +0100 Subject: [PATCH 31/69] Non-interactive mode for yulopti. --- test/tools/yulopti.cpp | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/test/tools/yulopti.cpp b/test/tools/yulopti.cpp index 752aaafa6..da5ae4871 100644 --- a/test/tools/yulopti.cpp +++ b/test/tools/yulopti.cpp @@ -162,6 +162,36 @@ public: } } + int runSteps(string source, string steps) + { + if (!parse(source)) + return 1; + + set reservedIdentifiers; + *m_ast = std::get(Disambiguator(m_dialect, *m_analysisInfo)(*m_ast)); + m_analysisInfo.reset(); + m_nameDispenser = make_shared(m_dialect, *m_ast, reservedIdentifiers); + + OptimiserStepContext context{ + m_dialect, + *m_nameDispenser, + reservedIdentifiers, + solidity::frontend::OptimiserSettings::standard().expectedExecutionsPerDeployment + }; + + map const& abbreviationMap = OptimiserSuite::stepAbbreviationToNameMap(); + for (char stepAbbreviation: steps) + if (auto abbreviationAndName = util::valueOrNullptr(abbreviationMap, stepAbbreviation)) + OptimiserSuite::allSteps().at(*abbreviationAndName)->run(context, *m_ast); + else + { + cerr << "Unknown optimizer step." << endl; + return 1; + } + cout << AsmPrinter{m_dialect}(*m_ast) << endl; + return 0; + } + void runInteractive(string source) { bool disambiguated = false; @@ -256,6 +286,11 @@ Allowed options)", po::value(), "input file" ) + ( + "steps", + po::value(), + "steps to execute non-interactively" + ) ("help", "Show this help screen."); // All positional options should be interpreted as input files @@ -292,7 +327,12 @@ Allowed options)", } if (arguments.count("input-file")) - YulOpti{}.runInteractive(input); + { + if (arguments.count("steps")) + return YulOpti{}.runSteps(input, arguments["steps"].as()); + else + YulOpti{}.runInteractive(input); + } else cout << options; From 95c973d6c2b12d39f1014d45f686c80d6aafb786 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Wed, 3 Nov 2021 12:12:37 +0100 Subject: [PATCH 32/69] Refactoring of optimiser suite and yulopti. --- libyul/optimiser/Suite.cpp | 7 +- libyul/optimiser/Suite.h | 17 +- test/tools/yulopti.cpp | 321 ++++++++++++++++++++----------------- 3 files changed, 184 insertions(+), 161 deletions(-) diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index bd81f7c0b..32ea08dbe 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -111,7 +111,10 @@ void OptimiserSuite::run( )(*_object.code)); Block& ast = *_object.code; - OptimiserSuite suite(_dialect, reservedIdentifiers, Debug::None, ast, _expectedExecutionsPerDeployment); + NameDispenser dispenser{_dialect, ast, reservedIdentifiers}; + OptimiserStepContext context{_dialect, dispenser, reservedIdentifiers, _expectedExecutionsPerDeployment}; + + OptimiserSuite suite(context, Debug::None); // Some steps depend on properties ensured by FunctionHoister, BlockFlattener, FunctionGrouper and // ForLoopInitRewriter. Run them first to be able to run arbitrary sequences safely. @@ -162,7 +165,7 @@ void OptimiserSuite::run( ast.statements.erase(ast.statements.begin()); } - suite.m_dispenser.reset(ast); + dispenser.reset(ast); NameSimplifier::run(suite.m_context, ast); VarNameCleaner::run(suite.m_context, ast); diff --git a/libyul/optimiser/Suite.h b/libyul/optimiser/Suite.h index 9b38ce542..3c85fc559 100644 --- a/libyul/optimiser/Suite.h +++ b/libyul/optimiser/Suite.h @@ -59,6 +59,8 @@ public: PrintStep, PrintChanges }; + OptimiserSuite(OptimiserStepContext& _context, Debug _debug = Debug::None): m_context(_context), m_debug(_debug) {} + /// The value nullopt for `_expectedExecutionsPerDeployment` represents creation code. static void run( Dialect const& _dialect, @@ -82,20 +84,7 @@ public: static std::map const& stepAbbreviationToNameMap(); private: - OptimiserSuite( - Dialect const& _dialect, - std::set const& _externallyUsedIdentifiers, - Debug _debug, - Block& _ast, - std::optional expectedExecutionsPerDeployment - ): - m_dispenser{_dialect, _ast, _externallyUsedIdentifiers}, - m_context{_dialect, m_dispenser, _externallyUsedIdentifiers, expectedExecutionsPerDeployment}, - m_debug(_debug) - {} - - NameDispenser m_dispenser; - OptimiserStepContext m_context; + OptimiserStepContext& m_context; Debug m_debug; }; diff --git a/test/tools/yulopti.cpp b/test/tools/yulopti.cpp index da5ae4871..5c4f00f0a 100644 --- a/test/tools/yulopti.cpp +++ b/test/tools/yulopti.cpp @@ -76,58 +76,66 @@ namespace po = boost::program_options; class YulOpti { public: - void printErrors() + static void printErrors(CharStream const& _charStream, ErrorList const& _errors) { SourceReferenceFormatter{ cerr, - SingletonCharStreamProvider(*m_charStream), + SingletonCharStreamProvider(_charStream), true, false - }.printErrorInformation(m_errors); + }.printErrorInformation(_errors); } - bool parse(string const& _input) + void parse(string const& _input) { - ErrorReporter errorReporter(m_errors); - m_charStream = make_shared(_input, ""); - m_ast = yul::Parser(errorReporter, m_dialect).parse(*m_charStream); - if (!m_ast || !errorReporter.errors().empty()) + ErrorList errors; + ErrorReporter errorReporter(errors); + CharStream _charStream(_input, ""); + try { - cerr << "Error parsing source." << endl; - printErrors(); - return false; + m_ast = yul::Parser(errorReporter, m_dialect).parse(_charStream); + if (!m_ast || !errorReporter.errors().empty()) + { + cerr << "Error parsing source." << endl; + printErrors(_charStream, errors); + throw std::runtime_error("Could not parse source."); + } + m_analysisInfo = make_unique(); + AsmAnalyzer analyzer( + *m_analysisInfo, + errorReporter, + m_dialect + ); + if (!analyzer.analyze(*m_ast) || !errorReporter.errors().empty()) + { + cerr << "Error analyzing source." << endl; + printErrors(_charStream, errors); + throw std::runtime_error("Could not analyze source."); + } } - m_analysisInfo = make_shared(); - AsmAnalyzer analyzer( - *m_analysisInfo, - errorReporter, - m_dialect - ); - if (!analyzer.analyze(*m_ast) || !errorReporter.errors().empty()) + catch(...) { - cerr << "Error analyzing source." << endl; - printErrors(); - return false; + cerr << "Fatal error during parsing: " << endl; + printErrors(_charStream, errors); + throw; } - return true; } void printUsageBanner( - map const& _optimizationSteps, map const& _extraOptions, size_t _columns ) { yulAssert(_columns > 0); - + auto const& optimiserSteps = OptimiserSuite::stepAbbreviationToNameMap(); auto hasShorterString = [](auto const& a, auto const& b) { return a.second.size() < b.second.size(); }; size_t longestDescriptionLength = std::max( - max_element(_optimizationSteps.begin(), _optimizationSteps.end(), hasShorterString)->second.size(), + max_element(optimiserSteps.begin(), optimiserSteps.end(), hasShorterString)->second.size(), max_element(_extraOptions.begin(), _extraOptions.end(), hasShorterString)->second.size() ); vector overlappingAbbreviations = - ranges::views::set_intersection(_extraOptions | ranges::views::keys, _optimizationSteps | ranges::views::keys) | + ranges::views::set_intersection(_extraOptions | ranges::views::keys, optimiserSteps | ranges::views::keys) | ranges::views::transform([](char _abbreviation){ return string(1, _abbreviation); }) | ranges::to(); @@ -141,7 +149,7 @@ public: ); vector> sortedOptions = - ranges::views::concat(_optimizationSteps, _extraOptions) | + ranges::views::concat(optimiserSteps, _extraOptions) | ranges::to>>() | ranges::actions::sort([](tuple const& _a, tuple const& _b) { return ( @@ -162,54 +170,28 @@ public: } } - int runSteps(string source, string steps) + void disambiguate() { - if (!parse(source)) - return 1; - - set reservedIdentifiers; *m_ast = std::get(Disambiguator(m_dialect, *m_analysisInfo)(*m_ast)); m_analysisInfo.reset(); - m_nameDispenser = make_shared(m_dialect, *m_ast, reservedIdentifiers); - - OptimiserStepContext context{ - m_dialect, - *m_nameDispenser, - reservedIdentifiers, - solidity::frontend::OptimiserSettings::standard().expectedExecutionsPerDeployment - }; - - map const& abbreviationMap = OptimiserSuite::stepAbbreviationToNameMap(); - for (char stepAbbreviation: steps) - if (auto abbreviationAndName = util::valueOrNullptr(abbreviationMap, stepAbbreviation)) - OptimiserSuite::allSteps().at(*abbreviationAndName)->run(context, *m_ast); - else - { - cerr << "Unknown optimizer step." << endl; - return 1; - } - cout << AsmPrinter{m_dialect}(*m_ast) << endl; - return 0; + m_nameDispenser.reset(*m_ast); } - void runInteractive(string source) + void runSteps(string _source, string _steps) { - bool disambiguated = false; + parse(_source); + disambiguate(); + OptimiserSuite{m_context}.runSequence(_steps, *m_ast); + cout << AsmPrinter{m_dialect}(*m_ast) << endl; + } + + void runInteractive(string _source, bool _disambiguated = false) + { + bool disambiguated = _disambiguated; while (true) { - cout << "----------------------" << endl; - cout << source << endl; - if (!parse(source)) - return; - set reservedIdentifiers; - if (!disambiguated) - { - *m_ast = std::get(Disambiguator(m_dialect, *m_analysisInfo)(*m_ast)); - m_analysisInfo.reset(); - m_nameDispenser = make_shared(m_dialect, *m_ast, reservedIdentifiers); - disambiguated = true; - } - map const& abbreviationMap = OptimiserSuite::stepAbbreviationToNameMap(); + parse(_source); + disambiguated = disambiguated || (disambiguate(), true); map const& extraOptions = { // QUIT starts with a non-letter character on purpose to get it to show up on top of the list {'#', ">>> QUIT <<<"}, @@ -217,104 +199,159 @@ public: {';', "StackCompressor"} }; - printUsageBanner(abbreviationMap, extraOptions, 4); + printUsageBanner(extraOptions, 4); cout << "? "; cout.flush(); - // TODO: handle EOF properly. char option = static_cast(readStandardInputChar()); cout << ' ' << option << endl; - OptimiserStepContext context{ - m_dialect, - *m_nameDispenser, - reservedIdentifiers, - solidity::frontend::OptimiserSettings::standard().expectedExecutionsPerDeployment - }; - - auto abbreviationAndName = abbreviationMap.find(option); - if (abbreviationAndName != abbreviationMap.end()) + try { - OptimiserStep const& step = *OptimiserSuite::allSteps().at(abbreviationAndName->second); - step.run(context, *m_ast); + switch (option) + { + case 4: + case '#': + return; + case ',': + VarNameCleaner::run(m_context, *m_ast); + // VarNameCleaner destroys the unique names guarantee of the disambiguator. + disambiguated = false; + break; + case ';': + { + Object obj; + obj.code = m_ast; + StackCompressor::run(m_dialect, obj, true, 16); + break; + } + default: + OptimiserSuite{m_context}.runSequence( + std::string_view(&option, 1), + *m_ast + ); + } + _source = AsmPrinter{m_dialect}(*m_ast); } - else switch (option) + catch (...) { - case '#': - return; - case ',': - VarNameCleaner::run(context, *m_ast); - // VarNameCleaner destroys the unique names guarantee of the disambiguator. - disambiguated = false; - break; - case ';': - { - Object obj; - obj.code = m_ast; - StackCompressor::run(m_dialect, obj, true, 16); - break; + cerr << endl << "Exception during optimiser step:" << endl; + cerr << boost::current_exception_diagnostic_information() << endl; } - default: - cerr << "Unknown option." << endl; - } - source = AsmPrinter{m_dialect}(*m_ast); + cout << "----------------------" << endl; + cout << _source << endl; } } private: - ErrorList m_errors; - shared_ptr m_charStream; shared_ptr m_ast; Dialect const& m_dialect{EVMDialect::strictAssemblyForEVMObjects(EVMVersion{})}; - shared_ptr m_analysisInfo; - shared_ptr m_nameDispenser; + unique_ptr m_analysisInfo; + set const m_reservedIdentifiers = {}; + NameDispenser m_nameDispenser{m_dialect, m_reservedIdentifiers}; + OptimiserStepContext m_context{ + m_dialect, + m_nameDispenser, + m_reservedIdentifiers, + solidity::frontend::OptimiserSettings::standard().expectedExecutionsPerDeployment + }; }; int main(int argc, char** argv) { - po::options_description options( - R"(yulopti, yul optimizer exploration tool. -Usage: yulopti [Options] -Reads as yul code and applies optimizer steps to it, -interactively read from stdin. - -Allowed options)", - po::options_description::m_default_line_length, - po::options_description::m_default_line_length - 23); - options.add_options() - ( - "input-file", - po::value(), - "input file" - ) - ( - "steps", - po::value(), - "steps to execute non-interactively" - ) - ("help", "Show this help screen."); - - // All positional options should be interpreted as input files - po::positional_options_description filesPositions; - filesPositions.add("input-file", 1); - - po::variables_map arguments; try { + bool nonInteractive = false; + po::options_description options( + R"(yulopti, yul optimizer exploration tool. + Usage: yulopti [Options] + Reads as yul code and applies optimizer steps to it, + interactively read from stdin. + In non-interactive mode a list of steps has to be provided. + If is -, yul code is read from stdin and run non-interactively. + + Allowed options)", + po::options_description::m_default_line_length, + po::options_description::m_default_line_length - 23); + options.add_options() + ( + "input-file", + po::value(), + "input file" + ) + ( + "steps", + po::value(), + "steps to execute non-interactively" + ) + ( + "non-interactive,n", + po::bool_switch(&nonInteractive)->default_value(false), + "stop after executing the provided steps" + ) + ("help,h", "Show this help screen."); + + // All positional options should be interpreted as input files + po::positional_options_description filesPositions; + filesPositions.add("input-file", 1); + + po::variables_map arguments; po::command_line_parser cmdLineParser(argc, argv); cmdLineParser.options(options).positional(filesPositions); po::store(cmdLineParser.run(), arguments); + po::notify(arguments); + + if (arguments.count("help")) + { + cout << options; + return 0; + } + + string input; + if (arguments.count("input-file")) + { + string filename = arguments["input-file"].as(); + if (filename == "-") + { + nonInteractive = true; + input = readUntilEnd(cin); + } + else + input = readFileAsString(arguments["input-file"].as()); + } + else + { + cout << options; + return 1; + } + + if (nonInteractive && !arguments.count("steps")) + { + cout << options; + return 1; + } + + YulOpti yulOpti; + bool disambiguated = false; + if (!nonInteractive) + cout << input << endl; + if (arguments.count("steps")) + { + string sequence = arguments["steps"].as(); + if (!nonInteractive) + cout << "----------------------" << endl; + yulOpti.runSteps(input, sequence); + disambiguated = true; + } + if (!nonInteractive) + yulOpti.runInteractive(input, disambiguated); + + return 0; } catch (po::error const& _exception) { cerr << _exception.what() << endl; return 1; } - - string input; - try - { - input = readFileAsString(arguments["input-file"].as()); - } catch (FileNotFound const& _exception) { cerr << "File not found:" << _exception.comment() << endl; @@ -325,16 +362,10 @@ Allowed options)", cerr << "Not a regular file:" << _exception.comment() << endl; return 1; } - - if (arguments.count("input-file")) + catch(...) { - if (arguments.count("steps")) - return YulOpti{}.runSteps(input, arguments["steps"].as()); - else - YulOpti{}.runInteractive(input); + cerr << endl << "Exception:" << endl; + cerr << boost::current_exception_diagnostic_information() << endl; + return 1; } - else - cout << options; - - return 0; } From b4a527039faa4517ab94a5fdb49be67b330c002d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20L=C3=B3pez?= Date: Wed, 3 Nov 2021 20:21:31 -0300 Subject: [PATCH 33/69] fixed example address payable --- docs/types/value-types.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/types/value-types.rst b/docs/types/value-types.rst index c02eea8a9..f849f3f7e 100644 --- a/docs/types/value-types.rst +++ b/docs/types/value-types.rst @@ -241,7 +241,7 @@ and to send Ether (in units of wei) to a payable address using the ``transfer`` .. code-block:: solidity :force: - address payable x = address(0x123); + address payable x = payable(0x123); address myAddress = address(this); if (x.balance < 10 && myAddress.balance >= 10) x.transfer(10); From 8e87c176715ae559cb3dc135a411936638fb762a Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Thu, 4 Nov 2021 11:44:31 +0100 Subject: [PATCH 34/69] Remove old compatibility patch to soljson.js. --- Changelog.md | 4 ++++ scripts/ci/build_emscripten.sh | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Changelog.md b/Changelog.md index f92e20c7e..b02bb80c3 100644 --- a/Changelog.md +++ b/Changelog.md @@ -31,6 +31,10 @@ Bugfixes: * Yul IR Generator: Do not output empty switches/if-bodies for empty contracts. +Build System: + * Remove obsolete compatibility workaround for emscripten builds. + + Important Bugfixes in Experimental Features: * 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. diff --git a/scripts/ci/build_emscripten.sh b/scripts/ci/build_emscripten.sh index f4b8d734d..7eac2486f 100755 --- a/scripts/ci/build_emscripten.sh +++ b/scripts/ci/build_emscripten.sh @@ -68,10 +68,6 @@ emcmake cmake \ -DTESTS=0 \ .. make soljson -# Patch soljson.js for backwards compatibility. -# TODO: remove this with 0.7. -# "viiiii" encodes the signature of the callback function. -sed -i -e 's/addFunction(func,sig){/addFunction(func,sig){sig=sig||"viiiii";/' libsolc/soljson.js cd .. mkdir -p upload From a0dee79ad2ec1b0e943e0a2180984e1443cc5661 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Thu, 4 Nov 2021 11:53:45 +0100 Subject: [PATCH 35/69] Remove install_deps script. --- docs/installing-solidity.rst | 15 +- scripts/Dockerfile | 3 +- scripts/install_deps.sh | 400 ----------------------------------- 3 files changed, 3 insertions(+), 415 deletions(-) delete mode 100755 scripts/install_deps.sh diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst index ea415f021..dbfa7a4c5 100644 --- a/docs/installing-solidity.rst +++ b/docs/installing-solidity.rst @@ -411,24 +411,13 @@ in Visual Studio 2019 Build Tools or Visual Studio 2019: .. _Visual Studio 2019: https://www.visualstudio.com/vs/ .. _Visual Studio 2019 Build Tools: https://www.visualstudio.com/downloads/#build-tools-for-visual-studio-2019 -Dependencies Helper Script --------------------------- - -We have a helper script which you can use to install all required external dependencies -on macOS, Windows and on numerous Linux distros. - -.. code-block:: bash - - ./scripts/install_deps.sh - -Or, on Windows: +We have a helper script which you can use to install all required external dependencies: .. code-block:: bat scripts\install_deps.ps1 -Note that the latter command will install ``boost`` and ``cmake`` to the ``deps`` subdirectory, while the former command -will attempt to install the dependencies globally. +This will install ``boost`` and ``cmake`` to the ``deps`` subdirectory. Clone the Repository -------------------- diff --git a/scripts/Dockerfile b/scripts/Dockerfile index 2b2de1e27..3a1c6a5a7 100644 --- a/scripts/Dockerfile +++ b/scripts/Dockerfile @@ -6,8 +6,7 @@ MAINTAINER chriseth WORKDIR /solidity # Build dependencies -ADD /scripts/install_deps.sh /solidity/scripts/install_deps.sh -RUN ./scripts/install_deps.sh +RUN apk update && apk add boost-dev boost-static build-base cmake git #Copy working directory on travis to the image COPY / $WORKDIR diff --git a/scripts/install_deps.sh b/scripts/install_deps.sh deleted file mode 100755 index 7540c8bdf..000000000 --- a/scripts/install_deps.sh +++ /dev/null @@ -1,400 +0,0 @@ -#!/usr/bin/env sh - -#------------------------------------------------------------------------------ -# Shell script for installing pre-requisite packages for solidity on a -# variety of Linux and other UNIX-derived platforms. -# -# This is an "infrastucture-as-code" alternative to the manual build -# instructions pages which we previously maintained at: -# https://docs.soliditylang.org/en/latest/installing-solidity.html -# -# The aim of this script is to simplify things down to the following basic -# flow for all supported operating systems: -# -# - git clone --recursive -# - ./scripts/install_deps.sh -# - cmake && make -# -# TODO - There is no support here yet for cross-builds in any form, only -# native builds. Expanding the functionality here to cover the mobile, -# wearable and SBC platforms covered by doublethink and EthEmbedded would -# also bring in support for Android, iOS, watchOS, tvOS, Tizen, Sailfish, -# Maemo, MeeGo and Yocto. -# -# The documentation for solidity is hosted at: -# -# https://docs.soliditylang.org -# -# ------------------------------------------------------------------------------ -# This file is part of solidity. -# -# solidity is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# solidity is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with solidity. If not, see -# -# (c) 2016 solidity contributors. -#------------------------------------------------------------------------------ - -set -e - -# Check for 'uname' and abort if it is not available. -uname -v > /dev/null 2>&1 || { echo >&2 "ERROR - solidity requires 'uname' to identify the platform."; exit 1; } - -# See http://unix.stackexchange.com/questions/92199/how-can-i-reliably-get-the-operating-systems-name -detect_linux_distro() { - if [ "$(command -v lsb_release)" ]; then - DISTRO=$(lsb_release -is) - elif [ -f /etc/os-release ]; then - # extract 'foo' from NAME=foo, only on the line with NAME=foo - DISTRO=$(sed -n -e 's/^NAME="\?\([^"]*\)"\?$/\1/p' /etc/os-release) - elif [ -f /etc/centos-release ]; then - DISTRO=CentOS - else - DISTRO='' - fi - echo "$DISTRO" -} - -case $(uname -s) in - -#------------------------------------------------------------------------------ -# macOS -#------------------------------------------------------------------------------ - - Darwin) - case $(sw_vers -productVersion | awk -F . '{print $1"."$2}') in - 10.9) - echo "Installing solidity dependencies on OS X 10.9 Mavericks." - ;; - 10.10) - echo "Installing solidity dependencies on OS X 10.10 Yosemite." - ;; - 10.11) - echo "Installing solidity dependencies on OS X 10.11 El Capitan." - ;; - 10.12) - echo "Installing solidity dependencies on macOS 10.12 Sierra." - ;; - 10.13) - echo "Installing solidity dependencies on macOS 10.13 High Sierra." - ;; - 10.14) - echo "Installing solidity dependencies on macOS 10.14 Mojave." - ;; - 10.15) - echo "Installing solidity dependencies on macOS 10.15 Catalina." - ;; - 11.0 | 11.1 | 11.2 | 11.3 | 11.4 | 11.5 | 11.6) - echo "Installing solidity dependencies on macOS 11.0 / 11.1 / 11.2 / 11.3 / 11.4 / 11.5 / 11.6 Big Sur." - ;; - *) - echo "Unsupported macOS version." - echo "We only support Mavericks, Yosemite, El Capitan, Sierra, High Sierra, Mojave, Catalina, and Big Sur." - exit 1 - ;; - esac - - # Check for Homebrew install and abort if it is not installed. - brew -v > /dev/null 2>&1 || { echo >&2 "ERROR - solidity requires a Homebrew install. See https://brew.sh."; exit 1; } - brew update - brew install boost - brew install cmake - if [ "$CI" = true ]; then - brew upgrade cmake - else - brew upgrade - fi - - ;; - -#------------------------------------------------------------------------------ -# FreeBSD -#------------------------------------------------------------------------------ - - FreeBSD) - echo "Installing solidity dependencies on FreeBSD." - echo "ERROR - 'install_deps.sh' doesn't have FreeBSD support yet." - echo "Please let us know if you see this error message, and we can work out what is missing." - echo "Drop us a message at https://gitter.im/ethereum/solidity-dev." - exit 1 - ;; - -#------------------------------------------------------------------------------ -# Linux -#------------------------------------------------------------------------------ - - Linux) - case $(detect_linux_distro) in - -#------------------------------------------------------------------------------ -# Arch Linux -#------------------------------------------------------------------------------ - - Arch*|ManjaroLinux) - #Arch - echo "Installing solidity dependencies on Arch Linux." - - # All our dependencies can be found in the Arch Linux official repositories. - # See https://wiki.archlinux.org/index.php/Official_repositories - sudo pacman -Syu \ - base-devel \ - boost \ - cmake \ - git \ - cvc4 - ;; - -#------------------------------------------------------------------------------ -# Alpine Linux -#------------------------------------------------------------------------------ - - "Alpine Linux") - #Alpine - echo "Installing solidity dependencies on Alpine Linux." - - # All our dependencies can be found in the Alpine Linux official repositories. - # See https://pkgs.alpinelinux.org/ - - apk update - apk add boost-dev boost-static build-base cmake git - - ;; - -#------------------------------------------------------------------------------ -# Debian -#------------------------------------------------------------------------------ - - Debian*|Raspbian) - #Debian - # shellcheck disable=SC1091 - . /etc/os-release - install_z3="" - case $VERSION_ID in - 8) - #jessie - echo "Installing solidity dependencies on Debian Jesse (8.x)." - ;; - 9) - #stretch - echo "Installing solidity dependencies on Debian Stretch (9.x)." - install_z3="libz3-dev" - ;; - 10) - #buster - echo "Installing solidity dependencies on Debian Buster (10.x)." - install_z3="libz3-dev" - ;; - *) - #other Debian - echo "Installing solidity dependencies on unknown Debian version." - echo "ERROR - This might not work, but we are trying anyway." - echo "Drop us a message at https://gitter.im/ethereum/solidity-dev" - install_z3="libz3-dev" - ;; - esac - - # Install "normal packages" - sudo apt-get -y update - sudo apt-get -y install \ - build-essential \ - cmake \ - g++ \ - gcc \ - git \ - libboost-all-dev \ - unzip \ - "$install_z3" - - - ;; - -#------------------------------------------------------------------------------ -# Fedora -#------------------------------------------------------------------------------ - - Fedora) - #Fedora - echo "Installing solidity dependencies on Fedora." - - # Install "normal packages" - # See https://fedoraproject.org/wiki/Package_management_system. - dnf install \ - autoconf \ - automake \ - boost-devel \ - boost-static \ - cmake \ - gcc \ - gcc-c++ \ - git \ - libtool - - ;; - -#------------------------------------------------------------------------------ -# OpenSUSE -#------------------------------------------------------------------------------ - - "openSUSE project") - #openSUSE - echo "Installing solidity dependencies on openSUSE." - echo "ERROR - 'install_deps.sh' doesn't have openSUSE support yet." - echo "See https://docs.soliditylang.org/en/latest/installing-solidity.html for manual instructions." - echo "If you would like to get 'install_deps.sh' working for openSUSE, that would be fantastic." - echo "See https://github.com/ethereum/webthree-umbrella/issues/552." - exit 1 - ;; -#------------------------------------------------------------------------------ -# Ubuntu -# -#------------------------------------------------------------------------------ - - Ubuntu|LinuxMint|Pop) - #LinuxMint is a distro on top of Ubuntu. - #Ubuntu - install_z3="" - case $(lsb_release -cs) in - trusty|qiana|rebecca|rafaela|rosa) - echo "Installing solidity dependencies on Ubuntu Trusty Tahr (14.04)." - echo "Or, you may also be running Linux Mint Qiana / Rebecca / Rafaela / Rosa (base: Ubuntu Trusty Tahr (14.04).)" - ;; - xenial|sarah|serena|sonya|sylvia) - echo "Installing solidity dependencies on Ubuntu Xenial Xerus (16.04)." - echo "Or, you may also be running Linux Mint Sarah / Serena / Sonya / Sylvia (base: Ubuntu Xenial Xerus (16.04).)" - install_z3="libz3-dev" - ;; - bionic) - echo "Installing solidity dependencies." - install_z3="libz3-dev" - ;; - focal) - echo "Installing solidity dependencies." - install_z3="libz3-dev" - ;; - hirsute) - echo "Installing solidity dependencies." - install_z3="libz3-dev" - ;; - betsy) - #do not try anything for betsy. - echo "Linux Mint Betsy is not supported at the moment as it runs off of Debian." - echo "We only support Sylvia, Sonya, Serena, Sarah, Rosa, Rafaela, Rebecca, and Qiana." - echo "See https://docs.soliditylang.org/en/latest/installing-solidity.html for manual instructions." - echo "If you would like to get your distro working, that would be fantastic." - echo "Drop us a message at https://gitter.im/ethereum/solidity-dev." - exit 1 - ;; - *) - #other Ubuntu - echo "ERROR - Unknown or unsupported Ubuntu version ($(lsb_release -cs))" - echo "ERROR - This might not work, but we are trying anyway." - echo "Please drop us a message at https://gitter.im/ethereum/solidity-dev." - echo "We only support Trusty, Xenial, Bionic, Focal, and Hirsute." - install_z3="libz3-dev" - ;; - esac - - sudo apt-get -y update - sudo apt-get -y install \ - build-essential \ - cmake \ - git \ - libboost-all-dev \ - "$install_z3" - if [ "$CI" = true ]; then - # install Z3 from PPA if the distribution does not provide it - if ! dpkg -l libz3-dev > /dev/null 2>&1 - then - sudo apt-add-repository -y ppa:hvr/z3 - sudo apt-get -y update - sudo apt-get -y install libz3-dev - fi - fi - ;; - -#------------------------------------------------------------------------------ -# CentOS -# CentOS needs some more testing. This is the general idea of packages -# needed, but some tweaking/improvements can definitely happen -#------------------------------------------------------------------------------ - CentOS*) - echo "Attention: CentOS 7 is currently not supported!"; - # FIXME: read -p and [[ ]] are bash features but our shebang says we're using sh - # shellcheck disable=SC2039 - read -p "This script will heavily modify your system in order to allow for compilation of Solidity. Are you sure? [Y/N]" -n 1 -r - # shellcheck disable=SC2039 - if [[ $REPLY =~ ^[Yy]$ ]]; then - # Make Sure we have the EPEL repos - sudo yum -y install epel-release - # Get g++ 4.8 - sudo rpm --import http://linuxsoft.cern.ch/cern/slc6X/i386/RPM-GPG-KEY-cern - wget -O /etc/yum.repos.d/slc6-devtoolset.repo http://linuxsoft.cern.ch/cern/devtoolset/slc6-devtoolset.repo - sudo yum -y install devtoolset-2-gcc devtoolset-2-gcc-c++ devtoolset-2-binutils - - # Enable the devtoolset2 usage so global gcc/g++ become the 4.8 one. - # As per https://gist.github.com/stephenturner/e3bc5cfacc2dc67eca8b, what you should do afterwards is - # to add this line: - # source /opt/rh/devtoolset-2/enable - # to your bashrc so that this happens automatically at login - scl enable devtoolset-2 bash - - # Get cmake - sudo yum -y remove cmake - sudo yum -y install cmake3 - sudo ln -s /usr/bin/cmake3 /usr/bin/cmake - - # Get latest boost thanks to this guy: http://vicendominguez.blogspot.de/2014/04/boost-c-library-rpm-packages-for-centos.html - sudo yum -y remove boost-devel - sudo wget https://bintray.com/vicendominguez/CentOS6/rpm -O /etc/yum.repos.d/bintray-vicendominguez-CentOS6.repo - sudo yum install boost-devel - else - echo "Aborted CentOS Solidity Dependency Installation"; - exit 1 - fi - - ;; - - - - - *) - -#------------------------------------------------------------------------------ -# Other (unknown) Linux -# Major and medium distros which we are missing would include Mint, CentOS, -# RHEL, Raspbian, Cygwin, OpenWrt, gNewSense, Trisquel and SteamOS. -#------------------------------------------------------------------------------ - - #other Linux - echo "ERROR - Unsupported or unidentified Linux distro." - echo "See https://docs.soliditylang.org/en/latest/installing-solidity.html for manual instructions." - echo "If you would like to get your distro working, that would be fantastic." - echo "Drop us a message at https://gitter.im/ethereum/solidity-dev." - exit 1 - ;; - esac - ;; - -#------------------------------------------------------------------------------ -# Other platform (not Linux, FreeBSD or macOS). -# Not sure what might end up here? -# Maybe OpenBSD, NetBSD, AIX, Solaris, HP-UX? -#------------------------------------------------------------------------------ - - *) - #other - echo "ERROR - Unsupported or unidentified operating system." - echo "See https://docs.soliditylang.org/en/latest/installing-solidity.html for manual instructions." - echo "If you would like to get your operating system working, that would be fantastic." - echo "Drop us a message at https://gitter.im/ethereum/solidity-dev." - ;; -esac From 99aa18c4f3d033422394902789a50c076fbdbad6 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 2 Nov 2021 17:48:59 +0100 Subject: [PATCH 36/69] Refactor: Only return output. --- .../backends/evm/ControlFlowGraphBuilder.cpp | 22 +++++++++---------- libyul/backends/evm/ControlFlowGraphBuilder.h | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/libyul/backends/evm/ControlFlowGraphBuilder.cpp b/libyul/backends/evm/ControlFlowGraphBuilder.cpp index 7e57b8257..66ee9fcd5 100644 --- a/libyul/backends/evm/ControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/ControlFlowGraphBuilder.cpp @@ -176,9 +176,9 @@ StackSlot ControlFlowGraphBuilder::operator()(Expression const& _expression) StackSlot ControlFlowGraphBuilder::operator()(FunctionCall const& _call) { - CFG::Operation const& operation = visitFunctionCall(_call); - yulAssert(operation.output.size() == 1, ""); - return operation.output.front(); + Stack const& output = visitFunctionCall(_call); + yulAssert(output.size() == 1, ""); + return output.front(); } void ControlFlowGraphBuilder::operator()(VariableDeclaration const& _varDecl) @@ -219,8 +219,8 @@ void ControlFlowGraphBuilder::operator()(ExpressionStatement const& _exprStmt) yulAssert(m_currentBlock, ""); std::visit(util::GenericVisitor{ [&](FunctionCall const& _call) { - CFG::Operation const& operation = visitFunctionCall(_call); - yulAssert(operation.output.empty(), ""); + Stack const& output = visitFunctionCall(_call); + yulAssert(output.empty(), ""); }, [&](auto const&) { yulAssert(false, ""); } }, _exprStmt.expression); @@ -418,7 +418,7 @@ void ControlFlowGraphBuilder::operator()(FunctionDefinition const& _function) } -CFG::Operation const& ControlFlowGraphBuilder::visitFunctionCall(FunctionCall const& _call) +Stack const& ControlFlowGraphBuilder::visitFunctionCall(FunctionCall const& _call) { yulAssert(m_scope, ""); yulAssert(m_currentBlock, ""); @@ -439,7 +439,7 @@ CFG::Operation const& ControlFlowGraphBuilder::visitFunctionCall(FunctionCall co }) | ranges::to, // operation move(builtinCall) - }); + }).output; } else { @@ -456,7 +456,7 @@ CFG::Operation const& ControlFlowGraphBuilder::visitFunctionCall(FunctionCall co }) | ranges::to, // operation CFG::FunctionCall{_call.debugData, function, _call} - }); + }).output; } } @@ -464,9 +464,9 @@ Stack ControlFlowGraphBuilder::visitAssignmentRightHandSide(Expression const& _e { return std::visit(util::GenericVisitor{ [&](FunctionCall const& _call) -> Stack { - CFG::Operation const& operation = visitFunctionCall(_call); - yulAssert(_expectedSlotCount == operation.output.size(), ""); - return operation.output; + Stack const& output = visitFunctionCall(_call); + yulAssert(_expectedSlotCount == output.size(), ""); + return output; }, [&](auto const& _identifierOrLiteral) -> Stack { yulAssert(_expectedSlotCount == 1, ""); diff --git a/libyul/backends/evm/ControlFlowGraphBuilder.h b/libyul/backends/evm/ControlFlowGraphBuilder.h index f99a879f6..8a6ec07c5 100644 --- a/libyul/backends/evm/ControlFlowGraphBuilder.h +++ b/libyul/backends/evm/ControlFlowGraphBuilder.h @@ -57,7 +57,7 @@ private: AsmAnalysisInfo const& _analysisInfo, Dialect const& _dialect ); - CFG::Operation const& visitFunctionCall(FunctionCall const&); + Stack const& visitFunctionCall(FunctionCall const&); Stack visitAssignmentRightHandSide(Expression const& _expression, size_t _expectedSlotCount); Scope::Function const& lookupFunction(YulString _name) const; From 929ed094ce5e8ab2561dcfe95a689007edd87c95 Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 4 Nov 2021 13:38:21 +0100 Subject: [PATCH 37/69] Register functions earlier. --- .../backends/evm/ControlFlowGraphBuilder.cpp | 32 ++++++++++++------- libyul/backends/evm/ControlFlowGraphBuilder.h | 1 + 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/libyul/backends/evm/ControlFlowGraphBuilder.cpp b/libyul/backends/evm/ControlFlowGraphBuilder.cpp index 66ee9fcd5..df271bb8d 100644 --- a/libyul/backends/evm/ControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/ControlFlowGraphBuilder.cpp @@ -239,6 +239,9 @@ void ControlFlowGraphBuilder::operator()(ExpressionStatement const& _exprStmt) void ControlFlowGraphBuilder::operator()(Block const& _block) { ScopedSaveAndRestore saveScope(m_scope, m_info.scopes.at(&_block).get()); + for (auto const& statement: _block.statements) + if (auto const* function = get_if(&statement)) + registerFunction(*function); for (auto const& statement: _block.statements) std::visit(*this, statement); } @@ -386,11 +389,26 @@ void ControlFlowGraphBuilder::operator()(FunctionDefinition const& _function) Scope::Function& function = std::get(m_scope->identifiers.at(_function.name)); m_graph.functions.emplace_back(&function); + CFG::FunctionInfo& functionInfo = m_graph.functionInfo.at(&function); + + ControlFlowGraphBuilder builder{m_graph, m_info, m_dialect}; + builder.m_currentFunction = &functionInfo; + builder.m_currentBlock = functionInfo.entry; + builder(_function.body); + builder.m_currentBlock->exit = CFG::BasicBlock::FunctionReturn{debugDataOf(_function), &functionInfo}; +} + +void ControlFlowGraphBuilder::registerFunction(FunctionDefinition const& _function) +{ + yulAssert(m_scope, ""); + yulAssert(m_scope->identifiers.count(_function.name), ""); + Scope::Function& function = std::get(m_scope->identifiers.at(_function.name)); + yulAssert(m_info.scopes.at(&_function.body), ""); Scope* virtualFunctionScope = m_info.scopes.at(m_info.virtualBlocks.at(&_function).get()).get(); yulAssert(virtualFunctionScope, ""); - auto&& [it, inserted] = m_graph.functionInfo.emplace(std::make_pair(&function, CFG::FunctionInfo{ + bool inserted = m_graph.functionInfo.emplace(std::make_pair(&function, CFG::FunctionInfo{ _function.debugData, function, &m_graph.makeBlock(debugDataOf(_function.body)), @@ -406,18 +424,10 @@ void ControlFlowGraphBuilder::operator()(FunctionDefinition const& _function) _retVar.debugData }; }) | ranges::to - })); - yulAssert(inserted, ""); - CFG::FunctionInfo& functionInfo = it->second; - - ControlFlowGraphBuilder builder{m_graph, m_info, m_dialect}; - builder.m_currentFunction = &functionInfo; - builder.m_currentBlock = functionInfo.entry; - builder(_function.body); - builder.m_currentBlock->exit = CFG::BasicBlock::FunctionReturn{debugDataOf(_function), &functionInfo}; + })).second; + yulAssert(inserted); } - Stack const& ControlFlowGraphBuilder::visitFunctionCall(FunctionCall const& _call) { yulAssert(m_scope, ""); diff --git a/libyul/backends/evm/ControlFlowGraphBuilder.h b/libyul/backends/evm/ControlFlowGraphBuilder.h index 8a6ec07c5..2a99cfe5b 100644 --- a/libyul/backends/evm/ControlFlowGraphBuilder.h +++ b/libyul/backends/evm/ControlFlowGraphBuilder.h @@ -57,6 +57,7 @@ private: AsmAnalysisInfo const& _analysisInfo, Dialect const& _dialect ); + void registerFunction(FunctionDefinition const& _function); Stack const& visitFunctionCall(FunctionCall const&); Stack visitAssignmentRightHandSide(Expression const& _expression, size_t _expectedSlotCount); From e7deedb7074ef8c68a49b30ef5e7503cf3eeca00 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Thu, 4 Nov 2021 11:17:28 +0100 Subject: [PATCH 38/69] Pass emscripten linker options only when linking. --- Changelog.md | 1 + cmake/EthCompilerSettings.cmake | 26 ++++++++++++++------------ libsolc/CMakeLists.txt | 2 +- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/Changelog.md b/Changelog.md index b02bb80c3..80bd749c7 100644 --- a/Changelog.md +++ b/Changelog.md @@ -32,6 +32,7 @@ Bugfixes: Build System: + * Pass linker-only emscripten options only when linking. * Remove obsolete compatibility workaround for emscripten builds. diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake index 0695c56a3..25c32f889 100644 --- a/cmake/EthCompilerSettings.cmake +++ b/cmake/EthCompilerSettings.cmake @@ -111,39 +111,41 @@ if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MA # http://stackoverflow.com/questions/21617158/how-to-silence-unused-command-line-argument-error-with-clang-without-disabling-i add_compile_options(-Qunused-arguments) elseif(EMSCRIPTEN) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --memory-init-file 0") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --memory-init-file 0") # Leave only exported symbols as public and aggressively remove others set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdata-sections -ffunction-sections -fvisibility=hidden") # Optimisation level set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3") # Re-enable exception catching (optimisations above -O1 disable it) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s DISABLE_EXCEPTION_CATCHING=0") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s DISABLE_EXCEPTION_CATCHING=0") # Remove any code related to exit (such as atexit) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s EXIT_RUNTIME=0") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s EXIT_RUNTIME=0") # Remove any code related to filesystem access - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s FILESYSTEM=0") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s FILESYSTEM=0") # Allow memory growth, but disable some optimisations - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s ALLOW_MEMORY_GROWTH=1") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s ALLOW_MEMORY_GROWTH=1") # Disable eval() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s DYNAMIC_EXECUTION=0") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s DYNAMIC_EXECUTION=0") # Disable greedy exception catcher - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s NODEJS_CATCH_EXIT=0") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s NODEJS_CATCH_EXIT=0") # Abort if linking results in any undefined symbols # Note: this is on by default in the CMake Emscripten module which we aren't using - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s ERROR_ON_UNDEFINED_SYMBOLS=1") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s ERROR_ON_UNDEFINED_SYMBOLS=1") # Disallow deprecated emscripten build options. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s STRICT=1") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s STRICT=1") # Export the Emscripten-generated auxiliary methods which are needed by solc-js. # Which methods of libsolc itself are exported is specified in libsolc/CMakeLists.txt. - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s EXTRA_EXPORTED_RUNTIME_METHODS=['cwrap','addFunction','removeFunction','UTF8ToString','lengthBytesUTF8','stringToUTF8','setValue']") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s EXTRA_EXPORTED_RUNTIME_METHODS=['cwrap','addFunction','removeFunction','UTF8ToString','lengthBytesUTF8','stringToUTF8','setValue']") # Build for webassembly target. - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s WASM=1") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s WASM=1") # Set webassembly build to synchronous loading. - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s WASM_ASYNC_COMPILATION=0") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s WASM_ASYNC_COMPILATION=0") # Output a single js file with the wasm binary embedded as base64 string. - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s SINGLE_FILE=1") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s SINGLE_FILE=1") # Allow new functions to be added to the wasm module via addFunction. - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s ALLOW_TABLE_GROWTH=1") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s ALLOW_TABLE_GROWTH=1") # Disable warnings about not being pure asm.js due to memory growth. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-almost-asm") endif() diff --git a/libsolc/CMakeLists.txt b/libsolc/CMakeLists.txt index 36dee4e24..776b97ca5 100644 --- a/libsolc/CMakeLists.txt +++ b/libsolc/CMakeLists.txt @@ -2,7 +2,7 @@ if (EMSCRIPTEN) # Specify which functions to export in soljson.js. # Note that additional Emscripten-generated methods needed by solc-js are # defined to be exported in cmake/EthCompilerSettings.cmake. - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s EXPORTED_FUNCTIONS='[\"_solidity_license\",\"_solidity_version\",\"_solidity_compile\",\"_solidity_alloc\",\"_solidity_free\",\"_solidity_reset\"]'") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s EXPORTED_FUNCTIONS='[\"_solidity_license\",\"_solidity_version\",\"_solidity_compile\",\"_solidity_alloc\",\"_solidity_free\",\"_solidity_reset\"]'") add_executable(soljson libsolc.cpp libsolc.h) target_link_libraries(soljson PRIVATE solidity) else() From dd8f12760b0ef6630a40d3a4d5eec6a3aadbe95f Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 4 Nov 2021 15:40:57 +0100 Subject: [PATCH 39/69] Introduce forEach for yul ast nodes. --- libyul/CMakeLists.txt | 2 - libyul/ControlFlowSideEffectsCollector.cpp | 2 - libyul/optimiser/ASTWalker.h | 31 +++++++++++++ libyul/optimiser/DataFlowAnalyzer.cpp | 26 +++++------ .../optimiser/FunctionDefinitionCollector.cpp | 36 --------------- .../optimiser/FunctionDefinitionCollector.h | 44 ------------------- libyul/optimiser/NameCollector.cpp | 26 ++++++++--- libyul/optimiser/NameCollector.h | 22 ++++------ libyul/optimiser/SSATransform.cpp | 22 +++------- libyul/optimiser/StackLimitEvader.cpp | 4 +- libyul/optimiser/StackToMemoryMover.cpp | 4 +- 11 files changed, 79 insertions(+), 140 deletions(-) delete mode 100644 libyul/optimiser/FunctionDefinitionCollector.cpp delete mode 100644 libyul/optimiser/FunctionDefinitionCollector.h diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index 30b97b5f7..3c980fbb8 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -140,8 +140,6 @@ add_library(yul optimiser/FullInliner.h optimiser/FunctionCallFinder.cpp optimiser/FunctionCallFinder.h - optimiser/FunctionDefinitionCollector.cpp - optimiser/FunctionDefinitionCollector.h optimiser/FunctionGrouper.cpp optimiser/FunctionGrouper.h optimiser/FunctionHoister.cpp diff --git a/libyul/ControlFlowSideEffectsCollector.cpp b/libyul/ControlFlowSideEffectsCollector.cpp index f907f83f5..bdcf70a78 100644 --- a/libyul/ControlFlowSideEffectsCollector.cpp +++ b/libyul/ControlFlowSideEffectsCollector.cpp @@ -18,8 +18,6 @@ #include -#include - #include #include diff --git a/libyul/optimiser/ASTWalker.h b/libyul/optimiser/ASTWalker.h index 107658dfc..cd98a90ca 100644 --- a/libyul/optimiser/ASTWalker.h +++ b/libyul/optimiser/ASTWalker.h @@ -102,4 +102,35 @@ protected: } }; +namespace detail +{ +template < + typename Node, + typename Visitor, + typename Base = std::conditional_t, ASTWalker, ASTModifier> +> +struct ForEach: Base +{ + template + ForEach(Callable&& _visitor): visitor(std::forward(_visitor)) {} + + using Base::operator(); + void operator()(Node& _node) override + { + visitor(_node); + Base::operator()(_node); + } + + Visitor visitor; +}; +} + +/// Helper function that traverses the AST and calls the visitor for each +/// node of a specific type. +template +void forEach(Entry&& _entry, Visitor&& _visitor) +{ + detail::ForEach>{std::forward(_visitor)}(std::forward(_entry)); +} + } diff --git a/libyul/optimiser/DataFlowAnalyzer.cpp b/libyul/optimiser/DataFlowAnalyzer.cpp index c6d9decaf..af25cde59 100644 --- a/libyul/optimiser/DataFlowAnalyzer.cpp +++ b/libyul/optimiser/DataFlowAnalyzer.cpp @@ -45,9 +45,9 @@ DataFlowAnalyzer::DataFlowAnalyzer( Dialect const& _dialect, map _functionSideEffects ): -m_dialect(_dialect), -m_functionSideEffects(std::move(_functionSideEffects)), -m_knowledgeBase(_dialect, m_value) + m_dialect(_dialect), + m_functionSideEffects(std::move(_functionSideEffects)), + m_knowledgeBase(_dialect, m_value) { if (auto const* builtin = _dialect.memoryStoreFunction(YulString{})) m_storeFunctionName[static_cast(StoreLoadLocation::Memory)] = builtin->name; @@ -123,9 +123,7 @@ void DataFlowAnalyzer::operator()(If& _if) joinKnowledge(storage, memory); - Assignments assignments; - assignments(_if.body); - clearValues(assignments.names()); + clearValues(assignedVariableNames(_if.body)); } void DataFlowAnalyzer::operator()(Switch& _switch) @@ -140,11 +138,10 @@ void DataFlowAnalyzer::operator()(Switch& _switch) (*this)(_case.body); joinKnowledge(storage, memory); - Assignments assignments; - assignments(_case.body); - assignedVariables += assignments.names(); + set variables = assignedVariableNames(_case.body); + assignedVariables += variables; // This is a little too destructive, we could retain the old values. - clearValues(assignments.names()); + clearValues(variables); clearKnowledgeIfInvalidated(_case.body); } for (auto& _case: _switch.cases) @@ -190,10 +187,9 @@ void DataFlowAnalyzer::operator()(ForLoop& _for) AssignmentsSinceContinue assignmentsSinceCont; assignmentsSinceCont(_for.body); - Assignments assignments; - assignments(_for.body); - assignments(_for.post); - clearValues(assignments.names()); + set assignedVariables = + assignedVariableNames(_for.body) + assignedVariableNames(_for.post); + clearValues(assignedVariables); // break/continue are tricky for storage and thus we almost always clear here. clearKnowledgeIfInvalidated(*_for.condition); @@ -205,7 +201,7 @@ void DataFlowAnalyzer::operator()(ForLoop& _for) clearValues(assignmentsSinceCont.names()); clearKnowledgeIfInvalidated(_for.body); (*this)(_for.post); - clearValues(assignments.names()); + clearValues(assignedVariables); clearKnowledgeIfInvalidated(*_for.condition); clearKnowledgeIfInvalidated(_for.post); clearKnowledgeIfInvalidated(_for.body); diff --git a/libyul/optimiser/FunctionDefinitionCollector.cpp b/libyul/optimiser/FunctionDefinitionCollector.cpp deleted file mode 100644 index dff57a32a..000000000 --- a/libyul/optimiser/FunctionDefinitionCollector.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* - This file is part of solidity. - - solidity is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - solidity is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with solidity. If not, see . -*/ - -#include -#include - -using namespace std; -using namespace solidity; -using namespace solidity::yul; - -map FunctionDefinitionCollector::run(Block const& _block) -{ - FunctionDefinitionCollector functionDefinitionCollector; - functionDefinitionCollector(_block); - return functionDefinitionCollector.m_functionDefinitions; -} - -void FunctionDefinitionCollector::operator()(FunctionDefinition const& _functionDefinition) -{ - m_functionDefinitions[_functionDefinition.name] = &_functionDefinition; - ASTWalker::operator()(_functionDefinition); -} diff --git a/libyul/optimiser/FunctionDefinitionCollector.h b/libyul/optimiser/FunctionDefinitionCollector.h deleted file mode 100644 index c9828aced..000000000 --- a/libyul/optimiser/FunctionDefinitionCollector.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - This file is part of solidity. - - solidity is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - solidity is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with solidity. If not, see . -*/ -/** - * AST walker that finds all function definitions and stores them into a map indexed by the function names. - */ -#pragma once - -#include - -#include - -namespace solidity::yul -{ - -/** - * AST walker that finds all function definitions and stores them into a map indexed by the function names. - * - * Prerequisite: Disambiguator - */ -class FunctionDefinitionCollector: ASTWalker -{ -public: - static std::map run(Block const& _block); -private: - using ASTWalker::operator(); - void operator()(FunctionDefinition const& _functionDefinition) override; - std::map m_functionDefinitions; -}; - -} diff --git a/libyul/optimiser/NameCollector.cpp b/libyul/optimiser/NameCollector.cpp index 69e627fbb..eca509f43 100644 --- a/libyul/optimiser/NameCollector.cpp +++ b/libyul/optimiser/NameCollector.cpp @@ -78,13 +78,6 @@ map ReferencesCounter::countReferences(Expression const& _exp return counter.references(); } -void Assignments::operator()(Assignment const& _assignment) -{ - for (auto const& var: _assignment.variableNames) - m_names.emplace(var.name); -} - - void AssignmentsSinceContinue::operator()(ForLoop const& _forLoop) { m_forLoopDepth++; @@ -109,3 +102,22 @@ void AssignmentsSinceContinue::operator()(FunctionDefinition const&) { yulAssert(false, ""); } + +std::set solidity::yul::assignedVariableNames(Block const& _code) +{ + std::set names; + forEach(_code, [&](Assignment const& _assignment) { + for (auto const& var: _assignment.variableNames) + names.emplace(var.name); + }); + return names; +} + +map solidity::yul::allFunctionDefinitions(Block const& _block) +{ + std::map result; + forEach(_block, [&](FunctionDefinition const& _function) { + result[_function.name] = &_function; + }); + return result; +} diff --git a/libyul/optimiser/NameCollector.h b/libyul/optimiser/NameCollector.h index 17afcec1b..8c9dc14ff 100644 --- a/libyul/optimiser/NameCollector.h +++ b/libyul/optimiser/NameCollector.h @@ -91,20 +91,6 @@ private: std::map m_references; }; -/** - * Specific AST walker that finds all variables that are assigned to. - */ -class Assignments: public ASTWalker -{ -public: - using ASTWalker::operator (); - void operator()(Assignment const& _assignment) override; - - std::set const& names() const { return m_names; } -private: - std::set m_names; -}; - /** * Collects all names from a given continue statement on onwards. * @@ -130,4 +116,12 @@ private: std::set m_names; }; +/// @returns the names of all variables that are assigned to inside @a _code. +/// (ignores variable declarations) +std::set assignedVariableNames(Block const& _code); + +/// @returns all function definitions anywhere in the AST. +/// Requires disambiguated source. +std::map allFunctionDefinitions(Block const& _block); + } diff --git a/libyul/optimiser/SSATransform.cpp b/libyul/optimiser/SSATransform.cpp index f0ce68c92..d86e6fbee 100644 --- a/libyul/optimiser/SSATransform.cpp +++ b/libyul/optimiser/SSATransform.cpp @@ -196,12 +196,7 @@ void IntroduceControlFlowSSA::operator()(ForLoop& _for) { yulAssert(_for.pre.statements.empty(), "For loop init rewriter not run."); - Assignments assignments; - assignments(_for.body); - assignments(_for.post); - - - for (auto const& var: assignments.names()) + for (auto const& var: assignedVariableNames(_for.body) + assignedVariableNames(_for.post)) if (m_variablesInScope.count(var)) m_variablesToReassign.insert(var); @@ -359,11 +354,7 @@ void PropagateValues::operator()(ForLoop& _for) { yulAssert(_for.pre.statements.empty(), "For loop init rewriter not run."); - Assignments assignments; - assignments(_for.body); - assignments(_for.post); - - for (auto const& var: assignments.names()) + for (auto const& var: assignedVariableNames(_for.body) + assignedVariableNames(_for.post)) m_currentVariableValues.erase(var); visit(*_for.condition); @@ -389,11 +380,10 @@ void PropagateValues::operator()(Block& _block) void SSATransform::run(OptimiserStepContext& _context, Block& _ast) { TypeInfo typeInfo(_context.dialect, _ast); - Assignments assignments; - assignments(_ast); - IntroduceSSA{_context.dispenser, assignments.names(), typeInfo}(_ast); - IntroduceControlFlowSSA{_context.dispenser, assignments.names(), typeInfo}(_ast); - PropagateValues{assignments.names()}(_ast); + set assignedVariables = assignedVariableNames(_ast); + IntroduceSSA{_context.dispenser, assignedVariables, typeInfo}(_ast); + IntroduceControlFlowSSA{_context.dispenser, assignedVariables, typeInfo}(_ast); + PropagateValues{assignedVariables}(_ast); } diff --git a/libyul/optimiser/StackLimitEvader.cpp b/libyul/optimiser/StackLimitEvader.cpp index b77bd4f38..b4b9d5469 100644 --- a/libyul/optimiser/StackLimitEvader.cpp +++ b/libyul/optimiser/StackLimitEvader.cpp @@ -18,8 +18,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -193,7 +193,7 @@ void StackLimitEvader::run( if (_unreachableVariables.count(function)) return; - map functionDefinitions = FunctionDefinitionCollector::run(*_object.code); + map functionDefinitions = allFunctionDefinitions(*_object.code); MemoryOffsetAllocator memoryOffsetAllocator{_unreachableVariables, callGraph.functionCalls, functionDefinitions}; uint64_t requiredSlots = memoryOffsetAllocator.run(); diff --git a/libyul/optimiser/StackToMemoryMover.cpp b/libyul/optimiser/StackToMemoryMover.cpp index dcc5f45f6..425680923 100644 --- a/libyul/optimiser/StackToMemoryMover.cpp +++ b/libyul/optimiser/StackToMemoryMover.cpp @@ -15,7 +15,7 @@ along with solidity. If not, see . */ #include -#include +#include #include #include @@ -87,7 +87,7 @@ void StackToMemoryMover::run( _context, memoryOffsetTracker, util::applyMap( - FunctionDefinitionCollector::run(_block), + allFunctionDefinitions(_block), util::mapTuple([](YulString _name, FunctionDefinition const* _funDef) { return make_pair(_name, _funDef->returnVariables); }), From 25c41546ee03f9567d67068dcc636c09367e9a32 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 3 Nov 2021 11:08:45 +0100 Subject: [PATCH 40/69] Function reference resolver. --- libyul/CMakeLists.txt | 2 + libyul/FunctionReferenceResolver.cpp | 60 ++++++++++++++++++++++++++++ libyul/FunctionReferenceResolver.h | 48 ++++++++++++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 libyul/FunctionReferenceResolver.cpp create mode 100644 libyul/FunctionReferenceResolver.h diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index 3c980fbb8..039e24ea9 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -40,6 +40,8 @@ add_library(yul Dialect.cpp Dialect.h Exceptions.h + FunctionReferenceResolver.cpp + FunctionReferenceResolver.h Object.cpp Object.h ObjectParser.cpp diff --git a/libyul/FunctionReferenceResolver.cpp b/libyul/FunctionReferenceResolver.cpp new file mode 100644 index 000000000..5df94237a --- /dev/null +++ b/libyul/FunctionReferenceResolver.cpp @@ -0,0 +1,60 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#include + +#include +#include + +#include + +using namespace std; +using namespace solidity::yul; +using namespace solidity::util; + +FunctionReferenceResolver::FunctionReferenceResolver(Block const& _ast) +{ + (*this)(_ast); + yulAssert(m_scopes.empty()); +} + +void FunctionReferenceResolver::operator()(FunctionCall const& _functionCall) +{ + for (auto&& scope: m_scopes | ranges::views::reverse) + if (FunctionDefinition const** function = util::valueOrNullptr(scope, _functionCall.functionName.name)) + { + m_functionReferences[&_functionCall] = *function; + break; + } + + // If we did not find anything, it was a builtin call. + + ASTWalker::operator()(_functionCall); +} + +void FunctionReferenceResolver::operator()(Block const& _block) +{ + m_scopes.emplace_back(); + for (auto const& statement: _block.statements) + if (auto const* function = get_if(&statement)) + m_scopes.back()[function->name] = function; + + ASTWalker::operator()(_block); + + m_scopes.pop_back(); +} diff --git a/libyul/FunctionReferenceResolver.h b/libyul/FunctionReferenceResolver.h new file mode 100644 index 000000000..8c1385adb --- /dev/null +++ b/libyul/FunctionReferenceResolver.h @@ -0,0 +1,48 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include + +namespace solidity::yul +{ + +/** + * Resolves references to user-defined functions in function calls. + * Assumes the code is correct, i.e. does not check for references to be valid or unique. + * + * Be careful not to iterate over the result - it is not deterministic. + */ +class FunctionReferenceResolver: private ASTWalker +{ +public: + explicit FunctionReferenceResolver(Block const& _ast); + std::map const& references() const { return m_functionReferences; } + +private: + using ASTWalker::operator(); + void operator()(FunctionCall const& _functionCall) override; + void operator()(Block const& _block) override; + + std::map m_functionReferences; + std::vector> m_scopes; +}; + + +} From 776ae466bcadda76fdffd976faa835f39995305a Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 3 Nov 2021 15:00:37 +0100 Subject: [PATCH 41/69] Control flow side effects on non-disambiguated source. --- libyul/ControlFlowSideEffectsCollector.cpp | 108 ++++++++++-------- libyul/ControlFlowSideEffectsCollector.h | 39 ++++--- libyul/optimiser/ConditionalSimplifier.cpp | 6 +- libyul/optimiser/ConditionalSimplifier.h | 6 +- libyul/optimiser/ConditionalUnsimplifier.cpp | 6 +- libyul/optimiser/DeadCodeEliminator.cpp | 2 +- libyul/optimiser/DeadCodeEliminator.h | 8 +- test/libyul/ControlFlowSideEffectsTest.cpp | 21 ++-- .../nondisambiguated.yul | 19 +++ 9 files changed, 128 insertions(+), 87 deletions(-) create mode 100644 test/libyul/controlFlowSideEffects/nondisambiguated.yul diff --git a/libyul/ControlFlowSideEffectsCollector.cpp b/libyul/ControlFlowSideEffectsCollector.cpp index bdcf70a78..6e96712a0 100644 --- a/libyul/ControlFlowSideEffectsCollector.cpp +++ b/libyul/ControlFlowSideEffectsCollector.cpp @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -35,16 +36,15 @@ using namespace solidity::yul; ControlFlowBuilder::ControlFlowBuilder(Block const& _ast) { - for (auto const& statement: _ast.statements) - if (auto const* function = get_if(&statement)) - (*this)(*function); + m_currentNode = newNode(); + (*this)(_ast); } void ControlFlowBuilder::operator()(FunctionCall const& _functionCall) { walkVector(_functionCall.arguments | ranges::views::reverse); newConnectedNode(); - m_currentNode->functionCall = _functionCall.functionName.name; + m_currentNode->functionCall = &_functionCall; } void ControlFlowBuilder::operator()(If const& _if) @@ -78,7 +78,9 @@ void ControlFlowBuilder::operator()(Switch const& _switch) void ControlFlowBuilder::operator()(FunctionDefinition const& _function) { ScopedSaveAndRestore currentNode(m_currentNode, nullptr); - yulAssert(!m_leave && !m_break && !m_continue, "Function hoister has not been used."); + ScopedSaveAndRestore leave(m_leave, nullptr); + ScopedSaveAndRestore _break(m_break, nullptr); + ScopedSaveAndRestore _continue(m_continue, nullptr); FunctionFlow flow; flow.exit = newNode(); @@ -90,7 +92,7 @@ void ControlFlowBuilder::operator()(FunctionDefinition const& _function) m_currentNode->successors.emplace_back(flow.exit); - m_functionFlows[_function.name] = move(flow); + m_functionFlows[&_function] = move(flow); m_leave = nullptr; } @@ -164,14 +166,17 @@ ControlFlowSideEffectsCollector::ControlFlowSideEffectsCollector( Block const& _ast ): m_dialect(_dialect), - m_cfgBuilder(_ast) + m_cfgBuilder(_ast), + m_functionReferences(FunctionReferenceResolver{_ast}.references()) { - for (auto&& [name, flow]: m_cfgBuilder.functionFlows()) + for (auto&& [function, flow]: m_cfgBuilder.functionFlows()) { yulAssert(!flow.entry->functionCall); - m_processedNodes[name] = {}; - m_pendingNodes[name].push_front(flow.entry); - m_functionSideEffects[name] = {false, false, false}; + yulAssert(function); + m_processedNodes[function] = {}; + m_pendingNodes[function].push_front(flow.entry); + m_functionSideEffects[function] = {false, false, false}; + m_functionCalls[function] = {}; } // Process functions while we have progress. For now, we are only interested @@ -180,8 +185,8 @@ ControlFlowSideEffectsCollector::ControlFlowSideEffectsCollector( while (progress) { progress = false; - for (auto const& functionName: m_pendingNodes | ranges::views::keys) - if (processFunction(functionName)) + for (FunctionDefinition const* function: m_pendingNodes | ranges::views::keys) + if (processFunction(*function)) progress = true; } @@ -190,57 +195,64 @@ ControlFlowSideEffectsCollector::ControlFlowSideEffectsCollector( // If we have not set `canContinue` by now, the function's exit // is not reachable. - for (auto&& [functionName, calls]: m_functionCalls) + // Now it is sufficient to handle the reachable function calls (`m_functionCalls`), + // we do not have to consider the control-flow graph anymore. + for (auto&& [function, calls]: m_functionCalls) { - ControlFlowSideEffects& sideEffects = m_functionSideEffects[functionName]; - auto _visit = [&, visited = std::set{}](YulString _function, auto&& _recurse) mutable { - if (sideEffects.canTerminate && sideEffects.canRevert) + yulAssert(function); + ControlFlowSideEffects& functionSideEffects = m_functionSideEffects[function]; + auto _visit = [&, visited = std::set{}](FunctionDefinition const& _function, auto&& _recurse) mutable { + // Worst side-effects already, stop searching. + if (functionSideEffects.canTerminate && functionSideEffects.canRevert) return; - if (!visited.insert(_function).second) + if (!visited.insert(&_function).second) return; - ControlFlowSideEffects const* calledSideEffects = nullptr; - if (BuiltinFunction const* f = _dialect.builtin(_function)) - calledSideEffects = &f->controlFlowSideEffects; - else - calledSideEffects = &m_functionSideEffects.at(_function); + for (FunctionCall const* call: m_functionCalls.at(&_function)) + { + ControlFlowSideEffects const& calledSideEffects = sideEffects(*call); + if (calledSideEffects.canTerminate) + functionSideEffects.canTerminate = true; + if (calledSideEffects.canRevert) + functionSideEffects.canRevert = true; - if (calledSideEffects->canTerminate) - sideEffects.canTerminate = true; - if (calledSideEffects->canRevert) - sideEffects.canRevert = true; - - set emptySet; - for (YulString callee: util::valueOrDefault(m_functionCalls, _function, emptySet)) - _recurse(callee, _recurse); + if (m_functionReferences.count(call)) + _recurse(*m_functionReferences.at(call), _recurse); + } }; - for (auto const& call: calls) - _visit(call, _visit); + _visit(*function, _visit); } - } -bool ControlFlowSideEffectsCollector::processFunction(YulString _name) +map ControlFlowSideEffectsCollector::functionSideEffectsNamed() const +{ + map result; + for (auto&& [function, sideEffects]: m_functionSideEffects) + yulAssert(result.insert({function->name, sideEffects}).second); + return result; +} + +bool ControlFlowSideEffectsCollector::processFunction(FunctionDefinition const& _function) { bool progress = false; - while (ControlFlowNode const* node = nextProcessableNode(_name)) + while (ControlFlowNode const* node = nextProcessableNode(_function)) { - if (node == m_cfgBuilder.functionFlows().at(_name).exit) + if (node == m_cfgBuilder.functionFlows().at(&_function).exit) { - m_functionSideEffects[_name].canContinue = true; + m_functionSideEffects[&_function].canContinue = true; return true; } for (ControlFlowNode const* s: node->successors) - recordReachabilityAndQueue(_name, s); + recordReachabilityAndQueue(_function, s); progress = true; } return progress; } -ControlFlowNode const* ControlFlowSideEffectsCollector::nextProcessableNode(YulString _functionName) +ControlFlowNode const* ControlFlowSideEffectsCollector::nextProcessableNode(FunctionDefinition const& _function) { - std::list& nodes = m_pendingNodes[_functionName]; + std::list& nodes = m_pendingNodes[&_function]; auto it = ranges::find_if(nodes, [this](ControlFlowNode const* _node) { return !_node->functionCall || sideEffects(*_node->functionCall).canContinue; }); @@ -252,22 +264,22 @@ ControlFlowNode const* ControlFlowSideEffectsCollector::nextProcessableNode(YulS return node; } -ControlFlowSideEffects const& ControlFlowSideEffectsCollector::sideEffects(YulString _functionName) const +ControlFlowSideEffects const& ControlFlowSideEffectsCollector::sideEffects(FunctionCall const& _call) const { - if (auto const* builtin = m_dialect.builtin(_functionName)) + if (auto const* builtin = m_dialect.builtin(_call.functionName.name)) return builtin->controlFlowSideEffects; else - return m_functionSideEffects.at(_functionName); + return m_functionSideEffects.at(m_functionReferences.at(&_call)); } void ControlFlowSideEffectsCollector::recordReachabilityAndQueue( - YulString _functionName, + FunctionDefinition const& _function, ControlFlowNode const* _node ) { if (_node->functionCall) - m_functionCalls[_functionName].insert(*_node->functionCall); - if (m_processedNodes[_functionName].insert(_node).second) - m_pendingNodes.at(_functionName).push_front(_node); + m_functionCalls[&_function].insert(_node->functionCall); + if (m_processedNodes[&_function].insert(_node).second) + m_pendingNodes.at(&_function).push_front(_node); } diff --git a/libyul/ControlFlowSideEffectsCollector.h b/libyul/ControlFlowSideEffectsCollector.h index f130294ba..a4ab2bfae 100644 --- a/libyul/ControlFlowSideEffectsCollector.h +++ b/libyul/ControlFlowSideEffectsCollector.h @@ -34,8 +34,8 @@ struct Dialect; struct ControlFlowNode { std::vector successors; - /// Name of the called function if the node calls a function. - std::optional functionCall; + /// Function call AST node, if present. + FunctionCall const* functionCall = nullptr; }; /** @@ -56,7 +56,7 @@ public: /// Computes the control-flows of all function defined in the block. /// Assumes the functions are hoisted to the topmost block. explicit ControlFlowBuilder(Block const& _ast); - std::map const& functionFlows() const { return m_functionFlows; } + std::map const& functionFlows() const { return m_functionFlows; } private: using ASTWalker::operator(); @@ -79,12 +79,14 @@ private: ControlFlowNode const* m_break = nullptr; ControlFlowNode const* m_continue = nullptr; - std::map m_functionFlows; + std::map m_functionFlows; }; /** - * Requires: Disambiguator, Function Hoister. + * Computes control-flow side-effects for user-defined functions. + * Source does not have to be disambiguated, unless you want the side-effects + * based on function names. */ class ControlFlowSideEffectsCollector { @@ -94,36 +96,43 @@ public: Block const& _ast ); - std::map const& functionSideEffects() const + std::map const& functionSideEffects() const { return m_functionSideEffects; } + /// Returns the side effects by function name, requires unique function names. + std::map functionSideEffectsNamed() const; private: /// @returns false if nothing could be processed. - bool processFunction(YulString _name); + bool processFunction(FunctionDefinition const& _function); /// @returns the next pending node of the function that is not /// a function call to a function that might not continue. /// De-queues the node or returns nullptr if no such node is found. - ControlFlowNode const* nextProcessableNode(YulString _functionName); + ControlFlowNode const* nextProcessableNode(FunctionDefinition const& _function); /// @returns the side-effects of either a builtin call or a user defined function /// call (as far as already computed). - ControlFlowSideEffects const& sideEffects(YulString _functionName) const; + ControlFlowSideEffects const& sideEffects(FunctionCall const& _call) const; /// Queues the given node to be processed (if not already visited) /// and if it is a function call, records that `_functionName` calls /// `*_node->functionCall`. - void recordReachabilityAndQueue(YulString _functionName, ControlFlowNode const* _node); + void recordReachabilityAndQueue(FunctionDefinition const& _function, ControlFlowNode const* _node); Dialect const& m_dialect; ControlFlowBuilder m_cfgBuilder; - std::map m_functionSideEffects; - std::map> m_pendingNodes; - std::map> m_processedNodes; - /// `x` is in `m_functionCalls[y]` if a direct call to `x` is reachable inside `y` - std::map> m_functionCalls; + /// Function references, but only for calls to user-defined functions. + std::map m_functionReferences; + /// Side effects of user-defined functions, is being constructod. + std::map m_functionSideEffects; + /// Control flow nodes still to process, per function. + std::map> m_pendingNodes; + /// Control flow nodes already processed, per function. + std::map> m_processedNodes; + /// Set of reachable function calls nodes in each function (including calls to builtins). + std::map> m_functionCalls; }; diff --git a/libyul/optimiser/ConditionalSimplifier.cpp b/libyul/optimiser/ConditionalSimplifier.cpp index 3a2e8aa4e..62d36520a 100644 --- a/libyul/optimiser/ConditionalSimplifier.cpp +++ b/libyul/optimiser/ConditionalSimplifier.cpp @@ -29,8 +29,10 @@ using namespace solidity::util; void ConditionalSimplifier::run(OptimiserStepContext& _context, Block& _ast) { - ControlFlowSideEffectsCollector sideEffects(_context.dialect, _ast); - ConditionalSimplifier{_context.dialect, sideEffects.functionSideEffects()}(_ast); + ConditionalSimplifier{ + _context.dialect, + ControlFlowSideEffectsCollector{_context.dialect, _ast}.functionSideEffectsNamed() + }(_ast); } void ConditionalSimplifier::operator()(Switch& _switch) diff --git a/libyul/optimiser/ConditionalSimplifier.h b/libyul/optimiser/ConditionalSimplifier.h index 57a6696c4..5df56476a 100644 --- a/libyul/optimiser/ConditionalSimplifier.h +++ b/libyul/optimiser/ConditionalSimplifier.h @@ -62,12 +62,12 @@ public: private: explicit ConditionalSimplifier( Dialect const& _dialect, - std::map const& _sideEffects + std::map _sideEffects ): - m_dialect(_dialect), m_functionSideEffects(_sideEffects) + m_dialect(_dialect), m_functionSideEffects(move(_sideEffects)) {} Dialect const& m_dialect; - std::map const& m_functionSideEffects; + std::map m_functionSideEffects; }; } diff --git a/libyul/optimiser/ConditionalUnsimplifier.cpp b/libyul/optimiser/ConditionalUnsimplifier.cpp index 752e06918..ef640ed7c 100644 --- a/libyul/optimiser/ConditionalUnsimplifier.cpp +++ b/libyul/optimiser/ConditionalUnsimplifier.cpp @@ -30,8 +30,10 @@ using namespace solidity::util; void ConditionalUnsimplifier::run(OptimiserStepContext& _context, Block& _ast) { - ControlFlowSideEffectsCollector sideEffects(_context.dialect, _ast); - ConditionalUnsimplifier{_context.dialect, sideEffects.functionSideEffects()}(_ast); + ConditionalUnsimplifier{ + _context.dialect, + ControlFlowSideEffectsCollector{_context.dialect, _ast}.functionSideEffectsNamed() + }(_ast); } void ConditionalUnsimplifier::operator()(Switch& _switch) diff --git a/libyul/optimiser/DeadCodeEliminator.cpp b/libyul/optimiser/DeadCodeEliminator.cpp index ad127a910..af8454684 100644 --- a/libyul/optimiser/DeadCodeEliminator.cpp +++ b/libyul/optimiser/DeadCodeEliminator.cpp @@ -40,7 +40,7 @@ void DeadCodeEliminator::run(OptimiserStepContext& _context, Block& _ast) ControlFlowSideEffectsCollector sideEffects(_context.dialect, _ast); DeadCodeEliminator{ _context.dialect, - sideEffects.functionSideEffects() + sideEffects.functionSideEffectsNamed() }(_ast); } diff --git a/libyul/optimiser/DeadCodeEliminator.h b/libyul/optimiser/DeadCodeEliminator.h index 98202fc94..2c166a836 100644 --- a/libyul/optimiser/DeadCodeEliminator.h +++ b/libyul/optimiser/DeadCodeEliminator.h @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -31,7 +32,6 @@ namespace solidity::yul { struct Dialect; struct OptimiserStepContext; -struct ControlFlowSideEffects; /** * Optimisation stage that removes unreachable code @@ -62,11 +62,11 @@ public: private: DeadCodeEliminator( Dialect const& _dialect, - std::map const& _sideEffects - ): m_dialect(_dialect), m_functionSideEffects(_sideEffects) {} + std::map _sideEffects + ): m_dialect(_dialect), m_functionSideEffects(move(_sideEffects)) {} Dialect const& m_dialect; - std::map const& m_functionSideEffects; + std::map m_functionSideEffects; }; } diff --git a/test/libyul/ControlFlowSideEffectsTest.cpp b/test/libyul/ControlFlowSideEffectsTest.cpp index aff3c564d..ce6c18c35 100644 --- a/test/libyul/ControlFlowSideEffectsTest.cpp +++ b/test/libyul/ControlFlowSideEffectsTest.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -61,19 +62,15 @@ TestCase::TestResult ControlFlowSideEffectsTest::run(ostream& _stream, string co if (!obj.code) BOOST_THROW_EXCEPTION(runtime_error("Parsing input failed.")); - std::map sideEffects = - ControlFlowSideEffectsCollector( - EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()), - *obj.code - ).functionSideEffects(); - - std::map controlFlowSideEffectsStr; - for (auto&& [fun, effects]: sideEffects) - controlFlowSideEffectsStr[fun.str()] = toString(effects); - + ControlFlowSideEffectsCollector sideEffects( + EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()), + *obj.code + ); m_obtainedResult.clear(); - for (auto&& [functionName, effect]: controlFlowSideEffectsStr) - m_obtainedResult += functionName + (effect.empty() ? ":" : ": " + effect) + "\n"; + forEach(*obj.code, [&](FunctionDefinition const& _fun) { + string effectStr = toString(sideEffects.functionSideEffects().at(&_fun)); + m_obtainedResult += _fun.name.str() + (effectStr.empty() ? ":" : ": " + effectStr) + "\n"; + }); return checkResult(_stream, _linePrefix, _formatted); } diff --git a/test/libyul/controlFlowSideEffects/nondisambiguated.yul b/test/libyul/controlFlowSideEffects/nondisambiguated.yul new file mode 100644 index 000000000..c3ed84bda --- /dev/null +++ b/test/libyul/controlFlowSideEffects/nondisambiguated.yul @@ -0,0 +1,19 @@ +{ + function a() { + { + function b() { if calldataloda(0) { return(0, 0) } } + b() + } + { + function b() { revert(0, 0) } + b() + } + } + function b() { + leave + revert(0, 0) + } +} +// ---- +// a: can revert +// b: can continue From 766d10b848684596e4fd6af026fa16d45b10ad18 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 3 Nov 2021 17:12:58 +0100 Subject: [PATCH 42/69] Tests. --- .../controlFlowSideEffects/nondisambiguated.yul | 14 +++++++++----- test/libyul/controlFlowSideEffects/recursion.yul | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/test/libyul/controlFlowSideEffects/nondisambiguated.yul b/test/libyul/controlFlowSideEffects/nondisambiguated.yul index c3ed84bda..4cc68c140 100644 --- a/test/libyul/controlFlowSideEffects/nondisambiguated.yul +++ b/test/libyul/controlFlowSideEffects/nondisambiguated.yul @@ -1,7 +1,7 @@ { function a() { { - function b() { if calldataloda(0) { return(0, 0) } } + function b() { if calldataload(0) { return(0, 0) } } b() } { @@ -9,11 +9,15 @@ b() } } - function b() { - leave - revert(0, 0) + { + function b() { + leave + revert(0, 0) + } } } // ---- -// a: can revert +// a: can terminate, can revert +// b: can terminate, can continue +// b: can revert // b: can continue diff --git a/test/libyul/controlFlowSideEffects/recursion.yul b/test/libyul/controlFlowSideEffects/recursion.yul index c4176d502..69cd4a2da 100644 --- a/test/libyul/controlFlowSideEffects/recursion.yul +++ b/test/libyul/controlFlowSideEffects/recursion.yul @@ -31,7 +31,7 @@ // b: can revert // c: // d: -// reg: can continue // x: // y: // z: +// reg: can continue From 0ee131c937f48116c69cc0276abb1f24da6d999e Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Thu, 4 Nov 2021 15:09:48 +0100 Subject: [PATCH 43/69] Update emscripten Dockerfile. --- .../docker/buildpack-deps/Dockerfile.emscripten | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/scripts/docker/buildpack-deps/Dockerfile.emscripten b/scripts/docker/buildpack-deps/Dockerfile.emscripten index 790a29634..9a3ca36af 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.emscripten +++ b/scripts/docker/buildpack-deps/Dockerfile.emscripten @@ -26,10 +26,14 @@ # contains a Makefile in the docker/ subdirectory that can be used to create the # required base image using: # -# make version=2.0.12 build +# make version=2.0.33 build # -FROM emscripten/emsdk:2.0.12 AS base -LABEL version="6" +# Note that emscripten is supposed to automatically install to $(em-config CACHE)/sysroot, but +# apparently this currently breaks due to conflicting compatibility headers. +# Using $(em-config CACHE)/sysroot/usr seems to work, though, and still has cmake find the +# dependencies automatically. +FROM emscripten/emsdk:2.0.33 AS base +LABEL version="7" ADD emscripten.jam /usr/src RUN set -ex; \ @@ -39,8 +43,8 @@ RUN set -ex; \ mkdir build; \ cd build; \ emcmake cmake \ + -DCMAKE_INSTALL_PREFIX=$(em-config CACHE)/sysroot/usr \ -DCMAKE_BUILD_TYPE=MinSizeRel \ - -DCMAKE_INSTALL_PREFIX=/emsdk/upstream/emscripten/system \ -DZ3_BUILD_LIBZ3_SHARED=OFF \ -DZ3_ENABLE_EXAMPLE_TARGETS=OFF \ -DZ3_BUILD_TEST_EXECUTABLES=OFF \ @@ -63,5 +67,5 @@ RUN set -ex; \ ./b2 toolset=emscripten link=static variant=release threading=single runtime-link=static \ --with-system --with-filesystem --with-test --with-program_options \ cxxflags="-s DISABLE_EXCEPTION_CATCHING=0 -Wno-unused-local-typedef -Wno-variadic-macros -Wno-c99-extensions -Wno-all" \ - --prefix=/emsdk/upstream/emscripten/system install; \ + --prefix=$(em-config CACHE)/sysroot/usr install; \ rm -r /usr/src/boost_1_75_0 From affeff18f5afbf4f27750179b3cb5ef07cadc0cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 30 Sep 2021 20:38:28 +0200 Subject: [PATCH 44/69] Don't ignore output selection in assembly mode --- Changelog.md | 1 + solc/CommandLineInterface.cpp | 50 +++++++---- solc/CommandLineParser.cpp | 17 ++++ .../args | 1 + .../evm_to_wasm_output_selection_asm_only/err | 1 + .../input.yul | 4 + .../output | 2 + .../args | 1 + .../err | 1 + .../input.yul | 4 + .../output | 87 +++++++++++++++++++ .../strict_asm_output_selection_asm_only/args | 1 + .../strict_asm_output_selection_asm_only/err | 1 + .../input.yul | 4 + .../output | 12 +++ .../strict_asm_output_selection_bin_only/args | 1 + .../strict_asm_output_selection_bin_only/err | 1 + .../input.yul | 4 + .../output | 5 ++ .../args | 1 + .../err | 1 + .../input.yul | 4 + .../output | 2 + .../strict_asm_output_selection_invalid/err | 2 +- .../args | 1 + .../err | 1 + .../input.yul | 4 + .../output | 7 ++ test/solc/CommandLineParser.cpp | 8 ++ 29 files changed, 213 insertions(+), 16 deletions(-) create mode 100644 test/cmdlineTests/evm_to_wasm_output_selection_asm_only/args create mode 100644 test/cmdlineTests/evm_to_wasm_output_selection_asm_only/err create mode 100644 test/cmdlineTests/evm_to_wasm_output_selection_asm_only/input.yul create mode 100644 test/cmdlineTests/evm_to_wasm_output_selection_asm_only/output create mode 100644 test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/args create mode 100644 test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/err create mode 100644 test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/input.yul create mode 100644 test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/output create mode 100644 test/cmdlineTests/strict_asm_output_selection_asm_only/args create mode 100644 test/cmdlineTests/strict_asm_output_selection_asm_only/err create mode 100644 test/cmdlineTests/strict_asm_output_selection_asm_only/input.yul create mode 100644 test/cmdlineTests/strict_asm_output_selection_asm_only/output create mode 100644 test/cmdlineTests/strict_asm_output_selection_bin_only/args create mode 100644 test/cmdlineTests/strict_asm_output_selection_bin_only/err create mode 100644 test/cmdlineTests/strict_asm_output_selection_bin_only/input.yul create mode 100644 test/cmdlineTests/strict_asm_output_selection_bin_only/output create mode 100644 test/cmdlineTests/strict_asm_output_selection_ewasm_only/args create mode 100644 test/cmdlineTests/strict_asm_output_selection_ewasm_only/err create mode 100644 test/cmdlineTests/strict_asm_output_selection_ewasm_only/input.yul create mode 100644 test/cmdlineTests/strict_asm_output_selection_ewasm_only/output create mode 100644 test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/args create mode 100644 test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/err create mode 100644 test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/input.yul create mode 100644 test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/output diff --git a/Changelog.md b/Changelog.md index 80bd749c7..97fd17763 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,6 +7,7 @@ Language Features: Compiler Features: * Commandline Interface: Accept nested brackets in step sequences passed to ``--yul-optimizations``. * Commandline Interface: Add ``--debug-info`` option for selecting how much extra debug information should be included in the produced EVM assembly and Yul code. + * Commandline Interface: Support ``--asm``, ``--bin``, ``--ir-optimized`` and ``--ewasm`` output selection options in assembler mode. * Commandline Interface: Use different colors when printing errors, warnings and infos. * SMTChecker: Output values for ``block.*``, ``msg.*`` and ``tx.*`` variables that are present in the called functions. * 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``. diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 9d2279910..49aa1b87f 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -1042,34 +1042,54 @@ bool CommandLineInterface::assemble(yul::AssemblyStack::Language _language, yul: yul::AssemblyStack& stack = assemblyStacks[src.first]; - sout() << endl << "Pretty printed source:" << endl; - sout() << stack.print() << endl; + if (m_options.compiler.outputs.irOptimized) + { + // NOTE: This actually outputs unoptimized code when the optimizer is disabled but + // 'ir' output in StandardCompiler works the same way. + sout() << endl << "Pretty printed source:" << endl; + sout() << stack.print() << endl; + } if (_language != yul::AssemblyStack::Language::Ewasm && _targetMachine == yul::AssemblyStack::Machine::Ewasm) { stack.translate(yul::AssemblyStack::Language::Ewasm); stack.optimize(); - sout() << endl << "==========================" << endl; - sout() << endl << "Translated source:" << endl; - sout() << stack.print() << endl; + // TODO: This isn't ewasm but it's only present when we're doing Yul->EWASM translation. + // It should get its own output flag in the future. + if (m_options.compiler.outputs.ewasm) + { + sout() << endl << "==========================" << endl; + sout() << endl << "Translated source:" << endl; + sout() << stack.print() << endl; + } } yul::MachineAssemblyObject object; object = stack.assemble(_targetMachine); object.bytecode->link(m_options.linker.libraries); - sout() << endl << "Binary representation:" << endl; - if (object.bytecode) - sout() << object.bytecode->toHex() << endl; - else - serr() << "No binary representation found." << endl; + if (m_options.compiler.outputs.binary) + { + sout() << endl << "Binary representation:" << endl; + if (object.bytecode) + sout() << object.bytecode->toHex() << endl; + else + serr() << "No binary representation found." << endl; + } - sout() << endl << "Text representation:" << endl; - if (!object.assembly.empty()) - sout() << object.assembly << endl; - else - serr() << "No text representation found." << endl; + solAssert(_targetMachine == yul::AssemblyStack::Machine::Ewasm || _targetMachine == yul::AssemblyStack::Machine::EVM, ""); + if ( + (_targetMachine == yul::AssemblyStack::Machine::EVM && m_options.compiler.outputs.asm_) || + (_targetMachine == yul::AssemblyStack::Machine::Ewasm && m_options.compiler.outputs.ewasm) + ) + { + sout() << endl << "Text representation:" << endl; + if (!object.assembly.empty()) + sout() << object.assembly << endl; + else + serr() << "No text representation found." << endl; + } } return true; diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index c3448ff8f..4bb5dfce6 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -450,6 +450,12 @@ bool CommandLineParser::parseOutputSelection() CompilerOutputs::componentMap() | ranges::views::keys | ranges::to(); + static set const assemblerModeOutputs = { + CompilerOutputs::componentName(&CompilerOutputs::asm_), + CompilerOutputs::componentName(&CompilerOutputs::binary), + CompilerOutputs::componentName(&CompilerOutputs::irOptimized), + CompilerOutputs::componentName(&CompilerOutputs::ewasm), + }; switch (_mode) { @@ -461,6 +467,7 @@ bool CommandLineParser::parseOutputSelection() case InputMode::CompilerWithASTImport: return contains(compilerModeOutputs, _outputName); case InputMode::Assembler: + return contains(assemblerModeOutputs, _outputName); case InputMode::StandardJson: case InputMode::Linker: return false; @@ -472,6 +479,16 @@ bool CommandLineParser::parseOutputSelection() for (auto&& [optionName, outputComponent]: CompilerOutputs::componentMap()) m_options.compiler.outputs.*outputComponent = (m_args.count(optionName) > 0); + if (m_options.input.mode == InputMode::Assembler && m_options.compiler.outputs == CompilerOutputs{}) + { + // In assembly mode keep the default outputs enabled for backwards-compatibility. + // TODO: Remove this (must be done in a breaking release). + m_options.compiler.outputs.asm_ = true; + m_options.compiler.outputs.binary = true; + m_options.compiler.outputs.irOptimized = true; + m_options.compiler.outputs.ewasm = true; + } + vector unsupportedOutputs; for (auto&& [optionName, outputComponent]: CompilerOutputs::componentMap()) if (m_options.compiler.outputs.*outputComponent && !outputSupported(m_options.input.mode, optionName)) diff --git a/test/cmdlineTests/evm_to_wasm_output_selection_asm_only/args b/test/cmdlineTests/evm_to_wasm_output_selection_asm_only/args new file mode 100644 index 000000000..f39038498 --- /dev/null +++ b/test/cmdlineTests/evm_to_wasm_output_selection_asm_only/args @@ -0,0 +1 @@ +--assemble --optimize --yul-dialect evm --machine ewasm --asm diff --git a/test/cmdlineTests/evm_to_wasm_output_selection_asm_only/err b/test/cmdlineTests/evm_to_wasm_output_selection_asm_only/err new file mode 100644 index 000000000..014a1178f --- /dev/null +++ b/test/cmdlineTests/evm_to_wasm_output_selection_asm_only/err @@ -0,0 +1 @@ +Warning: Yul is still experimental. Please use the output with care. diff --git a/test/cmdlineTests/evm_to_wasm_output_selection_asm_only/input.yul b/test/cmdlineTests/evm_to_wasm_output_selection_asm_only/input.yul new file mode 100644 index 000000000..4fa5ef66f --- /dev/null +++ b/test/cmdlineTests/evm_to_wasm_output_selection_asm_only/input.yul @@ -0,0 +1,4 @@ +{ + let x := 42 + sstore(0, x) +} diff --git a/test/cmdlineTests/evm_to_wasm_output_selection_asm_only/output b/test/cmdlineTests/evm_to_wasm_output_selection_asm_only/output new file mode 100644 index 000000000..d0cb60f39 --- /dev/null +++ b/test/cmdlineTests/evm_to_wasm_output_selection_asm_only/output @@ -0,0 +1,2 @@ + +======= evm_to_wasm_output_selection_asm_only/input.yul (Ewasm) ======= diff --git a/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/args b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/args new file mode 100644 index 000000000..48a844213 --- /dev/null +++ b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/args @@ -0,0 +1 @@ +--assemble --optimize --yul-dialect evm --machine ewasm --ewasm diff --git a/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/err b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/err new file mode 100644 index 000000000..014a1178f --- /dev/null +++ b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/err @@ -0,0 +1 @@ +Warning: Yul is still experimental. Please use the output with care. diff --git a/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/input.yul b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/input.yul new file mode 100644 index 000000000..4fa5ef66f --- /dev/null +++ b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/input.yul @@ -0,0 +1,4 @@ +{ + let x := 42 + sstore(0, x) +} diff --git a/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/output b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/output new file mode 100644 index 000000000..5f9a6c0fb --- /dev/null +++ b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/output @@ -0,0 +1,87 @@ + +======= evm_to_wasm_output_selection_ewasm_only/input.yul (Ewasm) ======= + +========================== + +Translated source: +object "object" { + code { + function main() + { + let hi := i64.shl(i64.extend_i32_u(bswap32(i32.wrap_i64(0))), 32) + let y := i64.or(hi, i64.extend_i32_u(bswap32(i32.wrap_i64(i64.shr_u(0, 32))))) + i64.store(0:i32, y) + i64.store(i32.add(0:i32, 8:i32), y) + i64.store(i32.add(0:i32, 16:i32), y) + i64.store(i32.add(0:i32, 24:i32), y) + i64.store(32:i32, y) + i64.store(i32.add(32:i32, 8:i32), y) + i64.store(i32.add(32:i32, 16:i32), y) + let hi_1 := i64.shl(i64.extend_i32_u(bswap32(i32.wrap_i64(42))), 32) + i64.store(i32.add(32:i32, 24:i32), i64.or(hi_1, i64.extend_i32_u(bswap32(i32.wrap_i64(i64.shr_u(42, 32)))))) + eth.storageStore(0:i32, 32:i32) + } + function bswap16(x:i32) -> y:i32 + { + y := i32.or(i32.and(i32.shl(x, 8:i32), 0xff00:i32), i32.and(i32.shr_u(x, 8:i32), 0xff:i32)) + } + function bswap32(x:i32) -> y:i32 + { + let hi:i32 := i32.shl(bswap16(x), 16:i32) + y := i32.or(hi, bswap16(i32.shr_u(x, 16:i32))) + } + } +} + + +Text representation: +(module + (import "ethereum" "storageStore" (func $eth.storageStore (param i32 i32))) + (memory $memory (export "memory") 1) + (export "main" (func $main)) + +(func $main + (local $hi i64) + (local $y i64) + (local $hi_1 i64) + (block $label_ + (local.set $hi (i64.shl (i64.extend_i32_u (call $bswap32 (i32.wrap_i64 (i64.const 0)))) (i64.const 32))) + (local.set $y (i64.or (local.get $hi) (i64.extend_i32_u (call $bswap32 (i32.wrap_i64 (i64.shr_u (i64.const 0) (i64.const 32))))))) + (i64.store (i32.const 0) (local.get $y)) + (i64.store (i32.add (i32.const 0) (i32.const 8)) (local.get $y)) + (i64.store (i32.add (i32.const 0) (i32.const 16)) (local.get $y)) + (i64.store (i32.add (i32.const 0) (i32.const 24)) (local.get $y)) + (i64.store (i32.const 32) (local.get $y)) + (i64.store (i32.add (i32.const 32) (i32.const 8)) (local.get $y)) + (i64.store (i32.add (i32.const 32) (i32.const 16)) (local.get $y)) + (local.set $hi_1 (i64.shl (i64.extend_i32_u (call $bswap32 (i32.wrap_i64 (i64.const 42)))) (i64.const 32))) + (i64.store (i32.add (i32.const 32) (i32.const 24)) (i64.or (local.get $hi_1) (i64.extend_i32_u (call $bswap32 (i32.wrap_i64 (i64.shr_u (i64.const 42) (i64.const 32))))))) + (call $eth.storageStore (i32.const 0) (i32.const 32)) + ) +) + +(func $bswap16 + (param $x i32) + (result i32) + (local $y i32) + (block $label__1 + (local.set $y (i32.or (i32.and (i32.shl (local.get $x) (i32.const 8)) (i32.const 65280)) (i32.and (i32.shr_u (local.get $x) (i32.const 8)) (i32.const 255)))) + + ) + (local.get $y) +) + +(func $bswap32 + (param $x i32) + (result i32) + (local $y i32) + (local $hi i32) + (block $label__2 + (local.set $hi (i32.shl (call $bswap16 (local.get $x)) (i32.const 16))) + (local.set $y (i32.or (local.get $hi) (call $bswap16 (i32.shr_u (local.get $x) (i32.const 16))))) + + ) + (local.get $y) +) + +) diff --git a/test/cmdlineTests/strict_asm_output_selection_asm_only/args b/test/cmdlineTests/strict_asm_output_selection_asm_only/args new file mode 100644 index 000000000..eff031170 --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_asm_only/args @@ -0,0 +1 @@ +--strict-assembly --optimize --asm diff --git a/test/cmdlineTests/strict_asm_output_selection_asm_only/err b/test/cmdlineTests/strict_asm_output_selection_asm_only/err new file mode 100644 index 000000000..014a1178f --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_asm_only/err @@ -0,0 +1 @@ +Warning: Yul is still experimental. Please use the output with care. diff --git a/test/cmdlineTests/strict_asm_output_selection_asm_only/input.yul b/test/cmdlineTests/strict_asm_output_selection_asm_only/input.yul new file mode 100644 index 000000000..4fa5ef66f --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_asm_only/input.yul @@ -0,0 +1,4 @@ +{ + let x := 42 + sstore(0, x) +} diff --git a/test/cmdlineTests/strict_asm_output_selection_asm_only/output b/test/cmdlineTests/strict_asm_output_selection_asm_only/output new file mode 100644 index 000000000..abe2143d3 --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_asm_only/output @@ -0,0 +1,12 @@ + +======= strict_asm_output_selection_asm_only/input.yul (EVM) ======= + +Text representation: + /* "strict_asm_output_selection_asm_only/input.yul":15:17 */ + 0x2a + /* "strict_asm_output_selection_asm_only/input.yul":29:30 */ + 0x00 + /* "strict_asm_output_selection_asm_only/input.yul":22:34 */ + sstore + /* "strict_asm_output_selection_asm_only/input.yul":0:36 */ + stop diff --git a/test/cmdlineTests/strict_asm_output_selection_bin_only/args b/test/cmdlineTests/strict_asm_output_selection_bin_only/args new file mode 100644 index 000000000..73ca2cca2 --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_bin_only/args @@ -0,0 +1 @@ +--strict-assembly --optimize --bin diff --git a/test/cmdlineTests/strict_asm_output_selection_bin_only/err b/test/cmdlineTests/strict_asm_output_selection_bin_only/err new file mode 100644 index 000000000..014a1178f --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_bin_only/err @@ -0,0 +1 @@ +Warning: Yul is still experimental. Please use the output with care. diff --git a/test/cmdlineTests/strict_asm_output_selection_bin_only/input.yul b/test/cmdlineTests/strict_asm_output_selection_bin_only/input.yul new file mode 100644 index 000000000..4fa5ef66f --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_bin_only/input.yul @@ -0,0 +1,4 @@ +{ + let x := 42 + sstore(0, x) +} diff --git a/test/cmdlineTests/strict_asm_output_selection_bin_only/output b/test/cmdlineTests/strict_asm_output_selection_bin_only/output new file mode 100644 index 000000000..3ffa826b8 --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_bin_only/output @@ -0,0 +1,5 @@ + +======= strict_asm_output_selection_bin_only/input.yul (EVM) ======= + +Binary representation: +602a60005500 diff --git a/test/cmdlineTests/strict_asm_output_selection_ewasm_only/args b/test/cmdlineTests/strict_asm_output_selection_ewasm_only/args new file mode 100644 index 000000000..bb147ae33 --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_ewasm_only/args @@ -0,0 +1 @@ +--strict-assembly --optimize --ewasm diff --git a/test/cmdlineTests/strict_asm_output_selection_ewasm_only/err b/test/cmdlineTests/strict_asm_output_selection_ewasm_only/err new file mode 100644 index 000000000..014a1178f --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_ewasm_only/err @@ -0,0 +1 @@ +Warning: Yul is still experimental. Please use the output with care. diff --git a/test/cmdlineTests/strict_asm_output_selection_ewasm_only/input.yul b/test/cmdlineTests/strict_asm_output_selection_ewasm_only/input.yul new file mode 100644 index 000000000..4fa5ef66f --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_ewasm_only/input.yul @@ -0,0 +1,4 @@ +{ + let x := 42 + sstore(0, x) +} diff --git a/test/cmdlineTests/strict_asm_output_selection_ewasm_only/output b/test/cmdlineTests/strict_asm_output_selection_ewasm_only/output new file mode 100644 index 000000000..f90f049aa --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_ewasm_only/output @@ -0,0 +1,2 @@ + +======= strict_asm_output_selection_ewasm_only/input.yul (EVM) ======= diff --git a/test/cmdlineTests/strict_asm_output_selection_invalid/err b/test/cmdlineTests/strict_asm_output_selection_invalid/err index 736eb2c8a..9c9104482 100644 --- a/test/cmdlineTests/strict_asm_output_selection_invalid/err +++ b/test/cmdlineTests/strict_asm_output_selection_invalid/err @@ -1 +1 @@ -The following outputs are not supported in assembler mode: --abi, --asm, --asm-json, --bin, --bin-runtime, --devdoc, --ewasm, --hashes, --ir, --ir-optimized, --metadata, --opcodes, --storage-layout, --userdoc. +The following outputs are not supported in assembler mode: --abi, --asm-json, --bin-runtime, --devdoc, --hashes, --ir, --metadata, --opcodes, --storage-layout, --userdoc. diff --git a/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/args b/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/args new file mode 100644 index 000000000..90b16d1f0 --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/args @@ -0,0 +1 @@ +--strict-assembly --optimize --ir-optimized diff --git a/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/err b/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/err new file mode 100644 index 000000000..014a1178f --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/err @@ -0,0 +1 @@ +Warning: Yul is still experimental. Please use the output with care. diff --git a/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/input.yul b/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/input.yul new file mode 100644 index 000000000..4fa5ef66f --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/input.yul @@ -0,0 +1,4 @@ +{ + let x := 42 + sstore(0, x) +} diff --git a/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/output b/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/output new file mode 100644 index 000000000..1fa4b72c7 --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/output @@ -0,0 +1,7 @@ + +======= strict_asm_output_selection_ir_optimized_only/input.yul (EVM) ======= + +Pretty printed source: +object "object" { + code { { sstore(0, 42) } } +} diff --git a/test/solc/CommandLineParser.cpp b/test/solc/CommandLineParser.cpp index a9ba08d81..dd5696c68 100644 --- a/test/solc/CommandLineParser.cpp +++ b/test/solc/CommandLineParser.cpp @@ -297,6 +297,10 @@ BOOST_AUTO_TEST_CASE(assembly_mode_options) "underflow," "divByZero", "--model-checker-timeout=5", // Ignored in assembly mode + "--asm", + "--bin", + "--ir-optimized", + "--ewasm", }; commandLine += assemblyOptions; if (expectedLanguage == AssemblyStack::Language::StrictAssembly || expectedLanguage == AssemblyStack::Language::Ewasm) @@ -333,6 +337,10 @@ BOOST_AUTO_TEST_CASE(assembly_mode_options) }; expectedOptions.formatting.coloredOutput = false; expectedOptions.formatting.withErrorIds = true; + expectedOptions.compiler.outputs.asm_ = true; + expectedOptions.compiler.outputs.binary = true; + expectedOptions.compiler.outputs.irOptimized = true; + expectedOptions.compiler.outputs.ewasm = true; if (expectedLanguage == AssemblyStack::Language::StrictAssembly || expectedLanguage == AssemblyStack::Language::Ewasm) { expectedOptions.optimizer.enabled = true; From 1a19d9a5cf75b3677baf7c5a85cd5e9500d8a4fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 3 Nov 2021 17:01:48 +0100 Subject: [PATCH 45/69] New CLI output in assembly mode: `--ewasm-ir` --- Changelog.md | 2 +- solc/CommandLineInterface.cpp | 4 +-- solc/CommandLineParser.cpp | 11 ++++-- solc/CommandLineParser.h | 2 ++ .../args | 1 + .../err | 1 + .../input.yul | 4 +++ .../output | 34 +++++++++++++++++++ .../output | 33 ------------------ .../output_selection_ewasm_ir_only/args | 1 + .../output_selection_ewasm_ir_only/err | 1 + .../output_selection_ewasm_ir_only/exit | 1 + .../output_selection_ewasm_ir_only/input.sol | 4 +++ .../args | 2 +- .../standard_cli_output_selection_invalid/err | 2 +- .../args | 1 + .../err | 1 + .../input.yul | 4 +++ .../output | 2 ++ test/solc/CommandLineParser.cpp | 4 +++ 20 files changed, 73 insertions(+), 42 deletions(-) create mode 100644 test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/args create mode 100644 test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/err create mode 100644 test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/input.yul create mode 100644 test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/output create mode 100644 test/cmdlineTests/output_selection_ewasm_ir_only/args create mode 100644 test/cmdlineTests/output_selection_ewasm_ir_only/err create mode 100644 test/cmdlineTests/output_selection_ewasm_ir_only/exit create mode 100644 test/cmdlineTests/output_selection_ewasm_ir_only/input.sol create mode 100644 test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/args create mode 100644 test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/err create mode 100644 test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/input.yul create mode 100644 test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/output diff --git a/Changelog.md b/Changelog.md index 97fd17763..3f7ea97c5 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,7 +7,7 @@ Language Features: Compiler Features: * Commandline Interface: Accept nested brackets in step sequences passed to ``--yul-optimizations``. * Commandline Interface: Add ``--debug-info`` option for selecting how much extra debug information should be included in the produced EVM assembly and Yul code. - * Commandline Interface: Support ``--asm``, ``--bin``, ``--ir-optimized`` and ``--ewasm`` output selection options in assembler mode. + * Commandline Interface: Support ``--asm``, ``--bin``, ``--ir-optimized``, ``--ewasm`` and ``--ewasm-ir`` output selection options in assembler mode. * Commandline Interface: Use different colors when printing errors, warnings and infos. * SMTChecker: Output values for ``block.*``, ``msg.*`` and ``tx.*`` variables that are present in the called functions. * 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``. diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 49aa1b87f..1d069f925 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -1055,9 +1055,7 @@ bool CommandLineInterface::assemble(yul::AssemblyStack::Language _language, yul: stack.translate(yul::AssemblyStack::Language::Ewasm); stack.optimize(); - // TODO: This isn't ewasm but it's only present when we're doing Yul->EWASM translation. - // It should get its own output flag in the future. - if (m_options.compiler.outputs.ewasm) + if (m_options.compiler.outputs.ewasmIR) { sout() << endl << "==========================" << endl; sout() << endl << "Translated source:" << endl; diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index 4bb5dfce6..9356c9662 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -446,15 +446,17 @@ bool CommandLineParser::parseOutputSelection() { static auto outputSupported = [](InputMode _mode, string_view _outputName) { - static set const compilerModeOutputs = + static set const compilerModeOutputs = ( CompilerOutputs::componentMap() | ranges::views::keys | - ranges::to(); + ranges::to() + ) - set{CompilerOutputs::componentName(&CompilerOutputs::ewasmIR)}; static set const assemblerModeOutputs = { CompilerOutputs::componentName(&CompilerOutputs::asm_), CompilerOutputs::componentName(&CompilerOutputs::binary), CompilerOutputs::componentName(&CompilerOutputs::irOptimized), CompilerOutputs::componentName(&CompilerOutputs::ewasm), + CompilerOutputs::componentName(&CompilerOutputs::ewasmIR), }; switch (_mode) @@ -487,6 +489,7 @@ bool CommandLineParser::parseOutputSelection() m_options.compiler.outputs.binary = true; m_options.compiler.outputs.irOptimized = true; m_options.compiler.outputs.ewasm = true; + m_options.compiler.outputs.ewasmIR = true; } vector unsupportedOutputs; @@ -709,6 +712,7 @@ General Information)").c_str(), (CompilerOutputs::componentName(&CompilerOutputs::ir).c_str(), "Intermediate Representation (IR) of all contracts (EXPERIMENTAL).") (CompilerOutputs::componentName(&CompilerOutputs::irOptimized).c_str(), "Optimized intermediate Representation (IR) of all contracts (EXPERIMENTAL).") (CompilerOutputs::componentName(&CompilerOutputs::ewasm).c_str(), "Ewasm text representation of all contracts (EXPERIMENTAL).") + (CompilerOutputs::componentName(&CompilerOutputs::ewasmIR).c_str(), "Intermediate representation (IR) converted to a form that can be translated directly into Ewasm text representation (EXPERIMENTAL).") (CompilerOutputs::componentName(&CompilerOutputs::signatureHashes).c_str(), "Function signature hashes of the contracts.") (CompilerOutputs::componentName(&CompilerOutputs::natspecUser).c_str(), "Natspec user documentation of all contracts.") (CompilerOutputs::componentName(&CompilerOutputs::natspecDev).c_str(), "Natspec developer documentation of all contracts.") @@ -923,11 +927,12 @@ bool CommandLineParser::processArgs() if (!checkMutuallyExclusive({g_strColor, g_strNoColor})) return false; - array const conflictingWithStopAfter{ + array const conflictingWithStopAfter{ CompilerOutputs::componentName(&CompilerOutputs::binary), CompilerOutputs::componentName(&CompilerOutputs::ir), CompilerOutputs::componentName(&CompilerOutputs::irOptimized), CompilerOutputs::componentName(&CompilerOutputs::ewasm), + CompilerOutputs::componentName(&CompilerOutputs::ewasmIR), g_strGas, CompilerOutputs::componentName(&CompilerOutputs::asm_), CompilerOutputs::componentName(&CompilerOutputs::asmJson), diff --git a/solc/CommandLineParser.h b/solc/CommandLineParser.h index 27a64c7b9..a1d13c690 100644 --- a/solc/CommandLineParser.h +++ b/solc/CommandLineParser.h @@ -78,6 +78,7 @@ struct CompilerOutputs {"ir", &CompilerOutputs::ir}, {"ir-optimized", &CompilerOutputs::irOptimized}, {"ewasm", &CompilerOutputs::ewasm}, + {"ewasm-ir", &CompilerOutputs::ewasmIR}, {"hashes", &CompilerOutputs::signatureHashes}, {"userdoc", &CompilerOutputs::natspecUser}, {"devdoc", &CompilerOutputs::natspecDev}, @@ -97,6 +98,7 @@ struct CompilerOutputs bool ir = false; bool irOptimized = false; bool ewasm = false; + bool ewasmIR = false; bool signatureHashes = false; bool natspecUser = false; bool natspecDev = false; diff --git a/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/args b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/args new file mode 100644 index 000000000..7c6526b56 --- /dev/null +++ b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/args @@ -0,0 +1 @@ +--assemble --optimize --yul-dialect evm --machine ewasm --ewasm-ir diff --git a/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/err b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/err new file mode 100644 index 000000000..014a1178f --- /dev/null +++ b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/err @@ -0,0 +1 @@ +Warning: Yul is still experimental. Please use the output with care. diff --git a/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/input.yul b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/input.yul new file mode 100644 index 000000000..4fa5ef66f --- /dev/null +++ b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/input.yul @@ -0,0 +1,4 @@ +{ + let x := 42 + sstore(0, x) +} diff --git a/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/output b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/output new file mode 100644 index 000000000..3124db17d --- /dev/null +++ b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/output @@ -0,0 +1,34 @@ + +======= evm_to_wasm_output_selection_ewasm_ir_only/input.yul (Ewasm) ======= + +========================== + +Translated source: +object "object" { + code { + function main() + { + let hi := i64.shl(i64.extend_i32_u(bswap32(i32.wrap_i64(0))), 32) + let y := i64.or(hi, i64.extend_i32_u(bswap32(i32.wrap_i64(i64.shr_u(0, 32))))) + i64.store(0:i32, y) + i64.store(i32.add(0:i32, 8:i32), y) + i64.store(i32.add(0:i32, 16:i32), y) + i64.store(i32.add(0:i32, 24:i32), y) + i64.store(32:i32, y) + i64.store(i32.add(32:i32, 8:i32), y) + i64.store(i32.add(32:i32, 16:i32), y) + let hi_1 := i64.shl(i64.extend_i32_u(bswap32(i32.wrap_i64(42))), 32) + i64.store(i32.add(32:i32, 24:i32), i64.or(hi_1, i64.extend_i32_u(bswap32(i32.wrap_i64(i64.shr_u(42, 32)))))) + eth.storageStore(0:i32, 32:i32) + } + function bswap16(x:i32) -> y:i32 + { + y := i32.or(i32.and(i32.shl(x, 8:i32), 0xff00:i32), i32.and(i32.shr_u(x, 8:i32), 0xff:i32)) + } + function bswap32(x:i32) -> y:i32 + { + let hi:i32 := i32.shl(bswap16(x), 16:i32) + y := i32.or(hi, bswap16(i32.shr_u(x, 16:i32))) + } + } +} diff --git a/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/output b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/output index 5f9a6c0fb..e8b306260 100644 --- a/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/output +++ b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/output @@ -1,39 +1,6 @@ ======= evm_to_wasm_output_selection_ewasm_only/input.yul (Ewasm) ======= -========================== - -Translated source: -object "object" { - code { - function main() - { - let hi := i64.shl(i64.extend_i32_u(bswap32(i32.wrap_i64(0))), 32) - let y := i64.or(hi, i64.extend_i32_u(bswap32(i32.wrap_i64(i64.shr_u(0, 32))))) - i64.store(0:i32, y) - i64.store(i32.add(0:i32, 8:i32), y) - i64.store(i32.add(0:i32, 16:i32), y) - i64.store(i32.add(0:i32, 24:i32), y) - i64.store(32:i32, y) - i64.store(i32.add(32:i32, 8:i32), y) - i64.store(i32.add(32:i32, 16:i32), y) - let hi_1 := i64.shl(i64.extend_i32_u(bswap32(i32.wrap_i64(42))), 32) - i64.store(i32.add(32:i32, 24:i32), i64.or(hi_1, i64.extend_i32_u(bswap32(i32.wrap_i64(i64.shr_u(42, 32)))))) - eth.storageStore(0:i32, 32:i32) - } - function bswap16(x:i32) -> y:i32 - { - y := i32.or(i32.and(i32.shl(x, 8:i32), 0xff00:i32), i32.and(i32.shr_u(x, 8:i32), 0xff:i32)) - } - function bswap32(x:i32) -> y:i32 - { - let hi:i32 := i32.shl(bswap16(x), 16:i32) - y := i32.or(hi, bswap16(i32.shr_u(x, 16:i32))) - } - } -} - - Text representation: (module (import "ethereum" "storageStore" (func $eth.storageStore (param i32 i32))) diff --git a/test/cmdlineTests/output_selection_ewasm_ir_only/args b/test/cmdlineTests/output_selection_ewasm_ir_only/args new file mode 100644 index 000000000..bccff6085 --- /dev/null +++ b/test/cmdlineTests/output_selection_ewasm_ir_only/args @@ -0,0 +1 @@ +--optimize --ewasm-ir diff --git a/test/cmdlineTests/output_selection_ewasm_ir_only/err b/test/cmdlineTests/output_selection_ewasm_ir_only/err new file mode 100644 index 000000000..52dd265b5 --- /dev/null +++ b/test/cmdlineTests/output_selection_ewasm_ir_only/err @@ -0,0 +1 @@ +The following outputs are not supported in compiler mode: --ewasm-ir. diff --git a/test/cmdlineTests/output_selection_ewasm_ir_only/exit b/test/cmdlineTests/output_selection_ewasm_ir_only/exit new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/test/cmdlineTests/output_selection_ewasm_ir_only/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/output_selection_ewasm_ir_only/input.sol b/test/cmdlineTests/output_selection_ewasm_ir_only/input.sol new file mode 100644 index 000000000..9755e16e7 --- /dev/null +++ b/test/cmdlineTests/output_selection_ewasm_ir_only/input.sol @@ -0,0 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 +pragma solidity *; + +contract C {} diff --git a/test/cmdlineTests/standard_cli_output_selection_invalid/args b/test/cmdlineTests/standard_cli_output_selection_invalid/args index f2deb3847..538c87097 100644 --- a/test/cmdlineTests/standard_cli_output_selection_invalid/args +++ b/test/cmdlineTests/standard_cli_output_selection_invalid/args @@ -1 +1 @@ ---ast-compact-json --asm --asm-json --opcodes --bin --bin-runtime --abi --ir --ir-optimized --ewasm --hashes --userdoc --devdoc --metadata --storage-layout +--ast-compact-json --asm --asm-json --opcodes --bin --bin-runtime --abi --ir --ir-optimized --ewasm --ewasm-ir --hashes --userdoc --devdoc --metadata --storage-layout diff --git a/test/cmdlineTests/standard_cli_output_selection_invalid/err b/test/cmdlineTests/standard_cli_output_selection_invalid/err index d6ed4d572..e9d24e61d 100644 --- a/test/cmdlineTests/standard_cli_output_selection_invalid/err +++ b/test/cmdlineTests/standard_cli_output_selection_invalid/err @@ -1 +1 @@ -The following outputs are not supported in standard JSON mode: --abi, --asm, --asm-json, --ast-compact-json, --bin, --bin-runtime, --devdoc, --ewasm, --hashes, --ir, --ir-optimized, --metadata, --opcodes, --storage-layout, --userdoc. +The following outputs are not supported in standard JSON mode: --abi, --asm, --asm-json, --ast-compact-json, --bin, --bin-runtime, --devdoc, --ewasm, --ewasm-ir, --hashes, --ir, --ir-optimized, --metadata, --opcodes, --storage-layout, --userdoc. diff --git a/test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/args b/test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/args new file mode 100644 index 000000000..647c63654 --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/args @@ -0,0 +1 @@ +--strict-assembly --optimize --ewasm-ir diff --git a/test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/err b/test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/err new file mode 100644 index 000000000..014a1178f --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/err @@ -0,0 +1 @@ +Warning: Yul is still experimental. Please use the output with care. diff --git a/test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/input.yul b/test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/input.yul new file mode 100644 index 000000000..4fa5ef66f --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/input.yul @@ -0,0 +1,4 @@ +{ + let x := 42 + sstore(0, x) +} diff --git a/test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/output b/test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/output new file mode 100644 index 000000000..8026a6e83 --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/output @@ -0,0 +1,2 @@ + +======= strict_asm_output_selection_ewasm_ir_only/input.yul (EVM) ======= diff --git a/test/solc/CommandLineParser.cpp b/test/solc/CommandLineParser.cpp index dd5696c68..23ea1efb1 100644 --- a/test/solc/CommandLineParser.cpp +++ b/test/solc/CommandLineParser.cpp @@ -198,7 +198,9 @@ BOOST_AUTO_TEST_CASE(cli_mode_options) true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, + true, }; + expectedOptions.compiler.outputs.ewasmIR = false; expectedOptions.compiler.estimateGas = true; expectedOptions.compiler.combinedJsonRequests = { true, true, true, true, true, @@ -301,6 +303,7 @@ BOOST_AUTO_TEST_CASE(assembly_mode_options) "--bin", "--ir-optimized", "--ewasm", + "--ewasm-ir", }; commandLine += assemblyOptions; if (expectedLanguage == AssemblyStack::Language::StrictAssembly || expectedLanguage == AssemblyStack::Language::Ewasm) @@ -341,6 +344,7 @@ BOOST_AUTO_TEST_CASE(assembly_mode_options) expectedOptions.compiler.outputs.binary = true; expectedOptions.compiler.outputs.irOptimized = true; expectedOptions.compiler.outputs.ewasm = true; + expectedOptions.compiler.outputs.ewasmIR = true; if (expectedLanguage == AssemblyStack::Language::StrictAssembly || expectedLanguage == AssemblyStack::Language::Ewasm) { expectedOptions.optimizer.enabled = true; From a7688a0eafcbc528f4a9d66e497a50e3712c4ca0 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Thu, 4 Nov 2021 19:24:12 +0100 Subject: [PATCH 46/69] Update emscripten to version 2.0.33. --- .circleci/config.yml | 4 ++-- Changelog.md | 1 + scripts/build_emscripten.sh | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e2ba6e2d0..9e5862cab 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -21,8 +21,8 @@ parameters: default: "solbuildpackpusher/solidity-buildpack-deps@sha256:c26a7ffc9fc243a4ec3105b9dc1edcdd964ad0e9665c83172b7ebda74bbf3021" emscripten-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:emscripten-6 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:092da5817bc032c91a806b4f73db2a1a31e5cc4c066d94d43eedd9f365df7154" + # solbuildpackpusher/solidity-buildpack-deps:emscripten-7 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:9ffcd0944433fe100e9433f2aa9ba5c21e096e758ad8a05a4a76feaed3d1f463" evm-version: type: string default: london diff --git a/Changelog.md b/Changelog.md index 80bd749c7..56a30bdae 100644 --- a/Changelog.md +++ b/Changelog.md @@ -34,6 +34,7 @@ Bugfixes: Build System: * Pass linker-only emscripten options only when linking. * Remove obsolete compatibility workaround for emscripten builds. + * Update emscripten to version 2.0.33. Important Bugfixes in Experimental Features: diff --git a/scripts/build_emscripten.sh b/scripts/build_emscripten.sh index 667d63708..7b8510026 100755 --- a/scripts/build_emscripten.sh +++ b/scripts/build_emscripten.sh @@ -34,7 +34,7 @@ else BUILD_DIR="$1" fi -# solbuildpackpusher/solidity-buildpack-deps:emscripten-6 +# solbuildpackpusher/solidity-buildpack-deps:emscripten-7 docker run -v "$(pwd):/root/project" -w /root/project \ - solbuildpackpusher/solidity-buildpack-deps@sha256:092da5817bc032c91a806b4f73db2a1a31e5cc4c066d94d43eedd9f365df7154 \ + solbuildpackpusher/solidity-buildpack-deps@sha256:9ffcd0944433fe100e9433f2aa9ba5c21e096e758ad8a05a4a76feaed3d1f463 \ ./scripts/ci/build_emscripten.sh "$BUILD_DIR" From b4f98b41bc9424be1d2cb659deaa9255b51cf3f2 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Fri, 5 Nov 2021 13:03:13 +0100 Subject: [PATCH 47/69] Minor fix to forEach on Yul AST nodes. --- libyul/optimiser/ASTWalker.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libyul/optimiser/ASTWalker.h b/libyul/optimiser/ASTWalker.h index cd98a90ca..b937f7eae 100644 --- a/libyul/optimiser/ASTWalker.h +++ b/libyul/optimiser/ASTWalker.h @@ -111,8 +111,7 @@ template < > struct ForEach: Base { - template - ForEach(Callable&& _visitor): visitor(std::forward(_visitor)) {} + ForEach(Visitor& _visitor): visitor(_visitor) {} using Base::operator(); void operator()(Node& _node) override @@ -121,7 +120,7 @@ struct ForEach: Base Base::operator()(_node); } - Visitor visitor; + Visitor& visitor; }; } @@ -130,7 +129,7 @@ struct ForEach: Base template void forEach(Entry&& _entry, Visitor&& _visitor) { - detail::ForEach>{std::forward(_visitor)}(std::forward(_entry)); + detail::ForEach{_visitor}(_entry); } } From 83308184f20f811d438df1bddc3921e7982279bd Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Fri, 5 Nov 2021 17:46:32 +0100 Subject: [PATCH 48/69] Remove outdated install_deps scripts. --- scripts/install_deps.bat | 61 ---------------------- scripts/install_deps.cmake | 99 ------------------------------------ scripts/install_static_z3.sh | 11 ---- 3 files changed, 171 deletions(-) delete mode 100644 scripts/install_deps.bat delete mode 100644 scripts/install_deps.cmake delete mode 100644 scripts/install_static_z3.sh diff --git a/scripts/install_deps.bat b/scripts/install_deps.bat deleted file mode 100644 index 61f7022a5..000000000 --- a/scripts/install_deps.bat +++ /dev/null @@ -1,61 +0,0 @@ -@ECHO OFF - -REM --------------------------------------------------------------------------- -REM Batch file for installing pre-requisite packages for solidity on -REM Windows platforms. That is implemented using CMake targets which -REM extract pre-built ZIPs hosted on GitHub into "deps\install_deps". -REM -REM See https://github.com/ethereum/cpp-dependencies -REM -REM The CMake files then point into that directory as an alternative -REM to the Homebrew, PPA or other global package server locations -REM available on Linux and UNIX platforms. -REM -REM The lack of a standard C++ packaging system for Windows is problematic -REM for us, and we have considered various options for improving the -REM situation, such as the following: -REM -REM See "Windows - Add support for Chocolatey packages" -REM https://github.com/ethereum/webthree-umbrella/issues/345 -REM -REM See "Windows - Try to use NuGet C++ packages" -REM https://github.com/ethereum/webthree-umbrella/issues/509 -REM -REM See "CM - Can we switch to NuGet delivery for our external dependencies" -REM https://github.com/ethereum/webthree-umbrella/issues/376 -REM -REM Another possible option, which would benefit build robustness on -REM multiple platforms, not just Windows, is to add dependencies as -REM git-submodules (or downloading on demand) so that we aren'targets -REM depend on platform-specific packaging systems at all. We have -REM already done just that for LLVM within evmjit. The downside of -REM that approach is that those dependencies then need to be -REM built-from-source, which adds time to the build process. It -REM gives us an unbeatable degree of control, though, because we -REM then perfectly control versioning and build flags for the binaries -REM for those packages. -REM -REM The documentation for solidity is hosted at: -REM -REM https://docs.soliditylang.org -REM -REM --------------------------------------------------------------------------- -REM This file is part of solidity. -REM -REM solidity is free software: you can redistribute it and/or modify -REM it under the terms of the GNU General Public License as published by -REM the Free Software Foundation, either version 3 of the License, or -REM (at your option) any later version. -REM -REM solidity is distributed in the hope that it will be useful, -REM but WITHOUT ANY WARRANTY; without even the implied warranty of -REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -REM GNU General Public License for more details. -REM -REM You should have received a copy of the GNU General Public License -REM along with solidity. If not, see -REM -REM Copyright (c) 2016 solidity contributors. -REM --------------------------------------------------------------------------- - -cmake -P scripts\install_deps.cmake diff --git a/scripts/install_deps.cmake b/scripts/install_deps.cmake deleted file mode 100644 index d90d4ec32..000000000 --- a/scripts/install_deps.cmake +++ /dev/null @@ -1,99 +0,0 @@ -get_filename_component(ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}/../deps" ABSOLUTE) - -set(CACHE_DIR "${ROOT_DIR}/cache") -set(PACKAGES_DIR "${ROOT_DIR}/packages") - -function(download URL DST_FILE STATUS) - set(TMP_FILE "${DST_FILE}.part") - - get_filename_component(FILE_NAME ${DST_FILE} NAME) - if (NOT EXISTS ${DST_FILE}) - message("Downloading ${FILE_NAME}") - file(DOWNLOAD ${URL} ${TMP_FILE} SHOW_PROGRESS STATUS DOWNLOAD_STATUS) - list(GET DOWNLOAD_STATUS 0 STATUS_CODE) - if (STATUS_CODE EQUAL 0) - file(RENAME ${TMP_FILE} ${DST_FILE}) - else() - file(REMOVE ${TMP_FILE}) - list(GET DOWNLOAD_STATUS 1 ERROR_MSG) - - message("ERROR! Downloading '${FILE_NAME}' failed.") - message(STATUS "URL: ${URL}") - message(STATUS "Error: ${STATUS_CODE} ${ERROR_MSG}") - set(STATUS FALSE PARENT_SCOPE) - return() - endif() - else() - message("Using cached ${FILE_NAME}") - endif() - set(STATUS TRUE PARENT_SCOPE) -endfunction(download) - -function(download_and_unpack PACKAGE_URL DST_DIR) - get_filename_component(FILE_NAME ${PACKAGE_URL} NAME) - - set(DST_FILE "${CACHE_DIR}/${FILE_NAME}") - set(TMP_FILE "${DST_FILE}.part") - - file(MAKE_DIRECTORY ${CACHE_DIR}) - file(MAKE_DIRECTORY ${DST_DIR}) - - download(${PACKAGE_URL} ${DST_FILE} STATUS) - - if (STATUS) - message("Unpacking ${FILE_NAME} to ${DST_DIR}") - execute_process(COMMAND ${CMAKE_COMMAND} -E tar -xf ${DST_FILE} - WORKING_DIRECTORY ${DST_DIR}) - endif() -endfunction(download_and_unpack) - -# Packs installed package binaries and headers into an archive. -function(create_package NAME DIR) - message("Creating package ${NAME}") - file(MAKE_DIRECTORY ${PACKAGES_DIR}) - - # To create an archive without addicional top level directory - # (like package-X.Y.Z) we need to know all top level files/dirs. - # Usually it is just "win64" dir. - file(GLOB TOP_FILES RELATIVE ${DIR} "${DIR}/*") - - set(PACKAGE_FILE "${PACKAGES_DIR}/${NAME}.tar.gz") - execute_process(COMMAND ${CMAKE_COMMAND} -E - tar -czf ${PACKAGE_FILE} ${TOP_FILES} - WORKING_DIRECTORY ${DIR}) -endfunction(create_package) - -# Downloads the source code of the package and unpacks it to dedicated 'src' -# dir. Also creates 'build' and 'install' dir to be used by a build script. -function(prepare_package_source NAME VERSION URL) - set(PACKAGE_NAME "${NAME}-${VERSION}") - - set(PACKAGE_DIR "${CACHE_DIR}/${PACKAGE_NAME}") - set(SOURCE_DIR "${PACKAGE_DIR}/src") - set(BUILD_DIR "${PACKAGE_DIR}/build") - set(INSTALL_DIR "${PACKAGE_DIR}/install") - - if (NOT EXISTS ${SOURCE_DIR}) - download_and_unpack(${URL} ${PACKAGE_DIR} STATUS) - file(GLOB ORIG_SOURCE_DIR_NAME "${PACKAGE_DIR}/*") - file(RENAME ${ORIG_SOURCE_DIR_NAME} ${SOURCE_DIR}) - endif() - - file(MAKE_DIRECTORY ${BUILD_DIR}) - file(MAKE_DIRECTORY ${INSTALL_DIR}) - - # Export names and dirs to be used by a package-specific build script. - set(PACKAGE_NAME ${PACKAGE_NAME} PARENT_SCOPE) - set(SOURCE_DIR ${SOURCE_DIR} PARENT_SCOPE) - set(BUILD_DIR ${BUILD_DIR} PARENT_SCOPE) - set(INSTALL_DIR ${INSTALL_DIR} PARENT_SCOPE) -endfunction() - -set(INSTALL_DIR "${ROOT_DIR}/install") -set(SERVER "https://github.com/ethereum/cpp-dependencies/releases/download/vs2017/") - -function(download_and_install PACKAGE_NAME) - download_and_unpack("${SERVER}${PACKAGE_NAME}.tar.gz" ${INSTALL_DIR}) -endfunction(download_and_install) - -download_and_install("boost-1.67.0") diff --git a/scripts/install_static_z3.sh b/scripts/install_static_z3.sh deleted file mode 100644 index 304ef410c..000000000 --- a/scripts/install_static_z3.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash - -set -eu - -git clone --depth 1 --branch z3-4.8.7 https://github.com/Z3Prover/z3.git -cd z3 -mkdir build -cd build -LDFLAGS="-static" cmake -DZ3_BUILD_LIBZ3_SHARED=OFF .. -make -j 4 -make install \ No newline at end of file From 063d00adc88c397230f31ff1803a1502b78af452 Mon Sep 17 00:00:00 2001 From: Shivam Rajput <75530356+phyBrackets@users.noreply.github.com> Date: Sun, 7 Nov 2021 10:41:48 +0530 Subject: [PATCH 49/69] 0.y.z makes more sense than 0.x for the current version. --- docs/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.rst b/docs/index.rst index a7bfbbe44..476cd8611 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -21,7 +21,7 @@ version of Solidity. Apart from exceptional cases, only the latest version recei `security fixes `_. Furthermore, breaking changes as well as new features are introduced regularly. We currently use -a 0.x version number `to indicate this fast pace of change `_. +a 0.y.z version number `to indicate this fast pace of change `_. .. warning:: From c6775bc01f59c04796bf4d15db9ec2ccd72710a2 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Sun, 7 Nov 2021 21:27:56 +0000 Subject: [PATCH 50/69] Include picosha2 in the license header --- cmake/templates/license.h.in | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/cmake/templates/license.h.in b/cmake/templates/license.h.in index 65276d8b4..6cdd2bb8a 100644 --- a/cmake/templates/license.h.in +++ b/cmake/templates/license.h.in @@ -6,9 +6,34 @@ static std::string const otherLicenses{R"(Most of the code is licensed under GPL parts are as follows: libkeccak-tiny: + The file libsolutil/Keccak256.cpp incorporates libkeccak-tiny. + A single-file implementation of SHA-3 and SHAKE implemented by David Leon Gil License: CC0, attribution kindly requested. Blame taken too, but not liability. +picosha2: + The file libsolutil/picosha2.h is imported. + + Copyright (C) 2017 okdshin + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + jsoncpp: The JsonCpp library's source code, including accompanying documentation, tests and demonstration applications, are licensed under the following From be552683c93ca8830a793ccd7805c7ad2e370228 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Mon, 8 Nov 2021 10:58:28 +0100 Subject: [PATCH 51/69] Remove incorrect outer block from for loop init rewriter documentation. --- docs/internals/optimizer.rst | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/docs/internals/optimizer.rst b/docs/internals/optimizer.rst index 93179c041..28c342902 100644 --- a/docs/internals/optimizer.rst +++ b/docs/internals/optimizer.rst @@ -429,11 +429,9 @@ is transformed to .. code-block:: text - { - Init... - for {} C { Post... } { - Body... - } + Init... + for {} C { Post... } { + Body... } This eases the rest of the optimization process because we can ignore From aa4d3cabf1e698bf871877d66d88d4bb48139611 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 8 Nov 2021 13:22:23 +0100 Subject: [PATCH 52/69] Clarify ``pure``. --- docs/contracts/functions.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/contracts/functions.rst b/docs/contracts/functions.rst index 7d1ce7256..ff49e4f28 100644 --- a/docs/contracts/functions.rst +++ b/docs/contracts/functions.rst @@ -222,6 +222,9 @@ Pure Functions -------------- Functions can be declared ``pure`` in which case they promise not to read from or modify the state. +In particular, it should be possible to evaluate a ``pure`` function at compile-time given +only its inputs and ``msg.data``, but without any knowledge of the current blockchain state. +This means that reading from ``immutable`` variables can be a non-pure operation. .. note:: If the compiler's EVM target is Byzantium or newer (default) the opcode ``STATICCALL`` is used, From a1aa9d2d90f2f7e7390408e9005d62c7159d4bd4 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 27 Oct 2021 17:26:44 +0200 Subject: [PATCH 53/69] Skip extcodesize check if return data is expected. --- Changelog.md | 1 + libsolidity/codegen/ExpressionCompiler.cpp | 18 +- .../codegen/ir/IRGeneratorForStatements.cpp | 20 +- .../output.json | 190 ++++++++++++++++++ .../output.json | 32 +-- .../abi_encode_calldata_slice.sol | 4 +- .../struct/struct_storage_ptr.sol | 2 +- .../abi_encode_calldata_slice.sol | 4 +- ...2_in_function_inherited_in_v1_contract.sol | 2 +- ...ode_v2_in_modifier_used_in_v1_contract.sol | 2 +- .../abiEncoderV2/calldata_array.sol | 2 +- .../arithmetics/check_var_init.sol | 2 +- .../array/fixed_arrays_as_return_type.sol | 2 +- .../array/function_array_cross_calls.sol | 2 +- .../semanticTests/array/reusing_memory.sol | 2 +- .../constructor/arrays_in_constructors.sol | 2 +- .../bytes_in_constructors_packer.sol | 2 +- .../constructor_function_complex.sol | 2 +- .../freeFunctions/new_operator.sol | 2 +- .../creation_function_call_no_args.sol | 2 +- .../functionCall/failed_create.sol | 4 +- .../functionTypes/store_function.sol | 2 +- .../immutable/multi_creation.sol | 2 +- .../address_overload_resolution.sol | 4 +- ...d_function_calldata_calldata_interface.sol | 2 +- ...ted_function_calldata_memory_interface.sol | 2 +- .../inheritance/member_notation_ctor.sol | 4 +- .../interface_inheritance_conversions.sol | 4 +- .../salted_create_with_value.sol | 2 +- .../semanticTests/smoke/alignment.sol | 2 +- .../various/code_access_content.sol | 2 +- .../various/code_access_create.sol | 2 +- .../various/external_types_in_calls.sol | 2 +- .../skip_dynamic_types_for_structs.sol | 2 +- .../various/staticcall_for_view_and_pure.sol | 6 +- 35 files changed, 270 insertions(+), 67 deletions(-) diff --git a/Changelog.md b/Changelog.md index f02004437..54088143b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -5,6 +5,7 @@ Language Features: Compiler Features: + * 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. * Commandline Interface: Accept nested brackets in step sequences passed to ``--yul-optimizations``. * Commandline Interface: Add ``--debug-info`` option for selecting how much extra debug information should be included in the produced EVM assembly and Yul code. * Commandline Interface: Use different colors when printing errors, warnings and infos. diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 731cf1a41..07d37c4c5 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -2630,9 +2630,21 @@ void ExpressionCompiler::appendExternalFunctionCall( // Check the target contract exists (has code) for non-low-level calls. if (funKind == FunctionType::Kind::External || funKind == FunctionType::Kind::DelegateCall) { - m_context << Instruction::DUP1 << Instruction::EXTCODESIZE << Instruction::ISZERO; - m_context.appendConditionalRevert(false, "Target contract does not contain code"); - existenceChecked = true; + size_t encodedHeadSize = 0; + for (auto const& t: returnTypes) + encodedHeadSize += t->decodingType()->calldataHeadSize(); + // We do not need to check extcodesize if we expect return data, since if there is no + // code, the call will return empty data and the ABI decoder will revert. + if ( + encodedHeadSize == 0 || + !haveReturndatacopy || + m_context.revertStrings() >= RevertStrings::Debug + ) + { + m_context << Instruction::DUP1 << Instruction::EXTCODESIZE << Instruction::ISZERO; + m_context.appendConditionalRevert(false, "Target contract does not contain code"); + existenceChecked = true; + } } if (_functionType.gasSet()) diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 6d7ee86f5..85b21bbdc 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -2451,8 +2451,10 @@ void IRGeneratorForStatements::appendExternalFunctionCall( appendCode() << "mstore(add(" << m_utils.allocateUnboundedFunction() << "() , " << to_string(returnInfo.estimatedReturnSize) << "), 0)\n"; } - Whiskers templ(R"(if iszero(extcodesize(
)) { () } - + Whiskers templ(R"( + + if iszero(extcodesize(
)) { () } + // storage for arguments and returned data let := () mstore(, ()) @@ -2477,6 +2479,18 @@ void IRGeneratorForStatements::appendExternalFunctionCall( } )"); templ("revertNoCode", m_utils.revertReasonIfDebugFunction("Target contract does not contain code")); + + // We do not need to check extcodesize if we expect return data: If there is no + // code, the call will return empty data and the ABI decoder will revert. + size_t encodedHeadSize = 0; + for (auto const& t: returnInfo.returnTypes) + encodedHeadSize += t->decodingType()->calldataHeadSize(); + bool const checkExtcodesize = + encodedHeadSize == 0 || + !m_context.evmVersion().supportsReturndata() || + m_context.revertStrings() >= RevertStrings::Debug; + templ("checkExtcodesize", checkExtcodesize); + templ("pos", m_context.newYulVariable()); templ("end", m_context.newYulVariable()); if (_functionCall.annotation().tryCall) @@ -2532,6 +2546,8 @@ void IRGeneratorForStatements::appendExternalFunctionCall( u256 gasNeededByCaller = evmasm::GasCosts::callGas(m_context.evmVersion()) + 10; if (funType.valueSet()) gasNeededByCaller += evmasm::GasCosts::callValueTransferGas; + if (!checkExtcodesize) + gasNeededByCaller += evmasm::GasCosts::callNewAccountGas; // we never know templ("gas", "sub(gas(), " + formatNumber(gasNeededByCaller) + ")"); } // Order is important here, STATICCALL might overlap with DELEGATECALL. diff --git a/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json b/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json index 0c529109a..773637b32 100644 --- a/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json +++ b/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json @@ -289,6 +289,19 @@ sub_0: assembly { address /* \"C\":403:411 this.f() */ extcodesize + tag_40 + jumpi + /* \"C\":79:428 contract C... */ + dup2 + dup3 + revert + /* \"C\":403:411 this.f() */ + tag_40: + /* \"C\":79:428 contract C... */ + /* \"C\":403:407 this */ + address + /* \"C\":403:411 this.f() */ + extcodesize iszero tag_43 jumpi @@ -316,6 +329,8 @@ sub_0: assembly { tag_45 jumpi dup1 + tag_41 + tag_40 swap3 tag_47 jumpi @@ -344,12 +359,22 @@ sub_0: assembly { swap1 jump\t// out /* \"C\":403:411 this.f() */ + tag_41: + tag_40: tag_47: /* \"C\":79:428 contract C... */ swap1 swap2 pop /* \"C\":403:411 this.f() */ + dup2 + iszero + tag_42 + jumpi + dup2 + iszero + tag_41 + jumpi returndatasize /* \"C\":79:428 contract C... */ 0x1f @@ -366,6 +391,10 @@ sub_0: assembly { dup4 lt or + iszero + tag_43 + iszero + tag_42 tag_51 jumpi pop @@ -379,26 +408,56 @@ sub_0: assembly { /* \"C\":392:422 stateVar + this.f() + immutVar */ tag_50 /* \"C\":79:428 contract C... */ + mstore + 0x24 + dup7 + revert + tag_43: + mstore + 0x24 + dup7 + revert + tag_42: swap5 0x40 mstore /* \"C\":403:411 this.f() */ + tag_44 + tag_43 returndatasize dup2 add swap1 tag_7 jump\t// in + tag_44: + swap1 + tag_43: + swap1 tag_53: swap2 dup2 swap4 pop + tag_42: + /* \"C\":392:411 stateVar + this.f() */ + tag_45 + tag_41: + /* \"C\":392:411 stateVar + this.f() */ + tag_44 jump(tag_48) /* \"C\":79:428 contract C... */ tag_51: shl(0xe0, 0x4e487b71) dup2 + dup6 + tag_5 + jump\t// in + tag_45: + dup6 + tag_5 + jump\t// in + tag_44: mstore 0x41 /* \"C\":403:411 this.f() */ @@ -422,12 +481,30 @@ sub_0: assembly { pop pop pop + /* \"C\":392:422 stateVar + this.f() + immutVar */ + tag_46 + /* \"C\":414:422 immutVar */ + immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") + /* \"C\":392:422 stateVar + this.f() + immutVar */ + /* \"C\":392:422 stateVar + this.f() + immutVar */ + tag_45 + /* \"C\":414:422 immutVar */ + immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") + /* \"C\":392:422 stateVar + this.f() + immutVar */ pop mload(0x40) swap1 returndatasize swap1 dup3 + tag_5 + jump\t// in + tag_46: + /* \"C\":336:337 _ */ + tag_5 + jump\t// in + tag_45: + /* \"C\":336:337 _ */ returndatacopy returndatasize swap1 @@ -453,6 +530,10 @@ sub_0: assembly { swap2 sub slt + iszero + tag_48 + iszero + tag_47 tag_55 jumpi mload @@ -464,6 +545,20 @@ sub_0: assembly { 0x00 dup1 revert + tag_48: + pop + mload + swap2 + swap1 + pop + jump\t// out + tag_47: + pop + mload + swap2 + swap1 + pop + jump\t// out auxdata: } @@ -799,6 +894,19 @@ sub_0: assembly { address /* \"C\":403:411 this.f() */ extcodesize + tag_40 + jumpi + /* \"D\":91:166 contract D is C(3)... */ + dup2 + dup3 + revert + /* \"C\":403:411 this.f() */ + tag_40: + /* \"D\":91:166 contract D is C(3)... */ + /* \"C\":403:407 this */ + address + /* \"C\":403:411 this.f() */ + extcodesize iszero tag_43 jumpi @@ -826,6 +934,8 @@ sub_0: assembly { tag_45 jumpi dup1 + tag_41 + tag_40 swap3 tag_47 jumpi @@ -854,12 +964,22 @@ sub_0: assembly { swap1 jump\t// out /* \"C\":403:411 this.f() */ + tag_41: + tag_40: tag_47: /* \"D\":91:166 contract D is C(3)... */ swap1 swap2 pop /* \"C\":403:411 this.f() */ + dup2 + iszero + tag_42 + jumpi + dup2 + iszero + tag_41 + jumpi returndatasize /* \"D\":91:166 contract D is C(3)... */ 0x1f @@ -876,6 +996,10 @@ sub_0: assembly { dup4 lt or + iszero + tag_43 + iszero + tag_42 tag_51 jumpi pop @@ -889,26 +1013,56 @@ sub_0: assembly { /* \"C\":392:422 stateVar + this.f() + immutVar */ tag_50 /* \"D\":91:166 contract D is C(3)... */ + mstore + 0x24 + dup7 + revert + tag_43: + mstore + 0x24 + dup7 + revert + tag_42: swap5 0x40 mstore /* \"C\":403:411 this.f() */ + tag_44 + tag_43 returndatasize dup2 add swap1 tag_7 jump\t// in + tag_44: + swap1 + tag_43: + swap1 tag_53: swap2 dup2 swap4 pop + tag_42: + /* \"C\":392:411 stateVar + this.f() */ + tag_45 + tag_41: + /* \"C\":392:411 stateVar + this.f() */ + tag_44 jump(tag_48) /* \"D\":91:166 contract D is C(3)... */ tag_51: shl(0xe0, 0x4e487b71) dup2 + dup6 + tag_5 + jump\t// in + tag_45: + dup6 + tag_5 + jump\t// in + tag_44: mstore 0x41 /* \"C\":403:411 this.f() */ @@ -931,6 +1085,16 @@ sub_0: assembly { swap4 pop pop + /* \"C\":392:422 stateVar + this.f() + immutVar */ + tag_46 + /* \"C\":414:422 immutVar */ + immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") + /* \"C\":392:422 stateVar + this.f() + immutVar */ + /* \"C\":392:422 stateVar + this.f() + immutVar */ + tag_45 + /* \"C\":414:422 immutVar */ + immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") + /* \"C\":392:422 stateVar + this.f() + immutVar */ pop pop mload(0x40) @@ -938,6 +1102,14 @@ sub_0: assembly { returndatasize swap1 dup3 + tag_5 + jump\t// in + tag_46: + /* \"C\":336:337 _ */ + tag_5 + jump\t// in + tag_45: + /* \"C\":336:337 _ */ returndatacopy returndatasize swap1 @@ -963,6 +1135,10 @@ sub_0: assembly { swap2 sub slt + iszero + tag_48 + iszero + tag_47 tag_55 jumpi mload @@ -974,6 +1150,20 @@ sub_0: assembly { 0x00 dup1 revert + tag_48: + pop + mload + swap2 + swap1 + pop + jump\t// out + tag_47: + pop + mload + swap2 + swap1 + pop + jump\t// out auxdata: } diff --git a/test/cmdlineTests/standard_debug_info_in_yul_location/output.json b/test/cmdlineTests/standard_debug_info_in_yul_location/output.json index 6a105aadd..2acd68ff7 100644 --- a/test/cmdlineTests/standard_debug_info_in_yul_location/output.json +++ b/test/cmdlineTests/standard_debug_info_in_yul_location/output.json @@ -526,7 +526,6 @@ object \"C_54\" { let expr_46_address := convert_t_contract$_C_$54_to_t_address(expr_45_address) let expr_46_functionSelector := 0x26121ff0 /// @src 0:410:418 \"this.f()\" - if iszero(extcodesize(expr_46_address)) { revert_error_0cc013b6b3b6beabea4e3a74a6d380f0df81852ca99887912475e1f66b2a2c20() } // storage for arguments and returned data let _10 := allocate_unbounded() @@ -640,7 +639,7 @@ object \"C_54\" { case 0x26121ff0 { if callvalue() { revert(_1, _1) } abi_decode(calldatasize()) - let ret := /** @src 0:286:305 \"constVar + immutVar\" */ checked_add_int256_566(/** @src 0:297:305 \"immutVar\" */ loadimmutable(\"8\")) + let ret := /** @src 0:286:305 \"constVar + immutVar\" */ checked_add_int256_556(/** @src 0:297:305 \"immutVar\" */ loadimmutable(\"8\")) /// @src 0:79:435 \"contract C...\" let memPos := mload(64) return(memPos, sub(abi_encode_int256(memPos, ret), memPos)) @@ -664,7 +663,7 @@ object \"C_54\" { if callvalue() { revert(_1, _1) } abi_decode(calldatasize()) let memPos_3 := mload(64) - return(memPos_3, sub(abi_encode_int256_565(memPos_3), memPos_3)) + return(memPos_3, sub(abi_encode_int256_555(memPos_3), memPos_3)) } } revert(0, 0) @@ -673,7 +672,7 @@ object \"C_54\" { { if slt(add(dataEnd, not(3)), 0) { revert(0, 0) } } - function abi_encode_int256_565(headStart) -> tail + function abi_encode_int256_555(headStart) -> tail { tail := add(headStart, 32) mstore(headStart, /** @src 0:124:126 \"41\" */ 0x29) @@ -690,7 +689,7 @@ object \"C_54\" { mstore(4, 0x11) revert(0, 0x24) } - function checked_add_int256_566(y) -> sum + function checked_add_int256_556(y) -> sum { if and(1, sgt(y, sub(shl(255, 1), 42))) { panic_error_0x11() } sum := add(/** @src 0:124:126 \"41\" */ 0x29, /** @src 0:79:435 \"contract C...\" */ y) @@ -712,13 +711,6 @@ object \"C_54\" { let ret := add(_3, 1) sstore(_2, ret) /// @src 0:410:418 \"this.f()\" - if iszero(extcodesize(/** @src 0:410:414 \"this\" */ address())) - /// @src 0:410:418 \"this.f()\" - { - /// @src 0:79:435 \"contract C...\" - revert(_2, _2) - } - /// @src 0:410:418 \"this.f()\" let _4 := /** @src 0:79:435 \"contract C...\" */ mload(64) /// @src 0:410:418 \"this.f()\" mstore(_4, /** @src 0:79:435 \"contract C...\" */ shl(228, 0x026121ff)) @@ -1359,7 +1351,6 @@ object \"D_72\" { let expr_46_address := convert_t_contract$_C_$54_to_t_address(expr_45_address) let expr_46_functionSelector := 0x26121ff0 /// @src 0:410:418 \"this.f()\" - if iszero(extcodesize(expr_46_address)) { revert_error_0cc013b6b3b6beabea4e3a74a6d380f0df81852ca99887912475e1f66b2a2c20() } // storage for arguments and returned data let _10 := allocate_unbounded() @@ -1481,7 +1472,7 @@ object \"D_72\" { case 0x26121ff0 { if callvalue() { revert(_1, _1) } abi_decode(calldatasize()) - let ret := /** @src 0:286:305 \"constVar + immutVar\" */ checked_add_int256_566(/** @src 0:297:305 \"immutVar\" */ loadimmutable(\"8\")) + let ret := /** @src 0:286:305 \"constVar + immutVar\" */ checked_add_int256_556(/** @src 0:297:305 \"immutVar\" */ loadimmutable(\"8\")) /// @src 1:91:166 \"contract D is C(3)...\" let memPos := mload(64) return(memPos, sub(abi_encode_int256(memPos, ret), memPos)) @@ -1505,7 +1496,7 @@ object \"D_72\" { if callvalue() { revert(_1, _1) } abi_decode(calldatasize()) let memPos_3 := mload(64) - return(memPos_3, sub(abi_encode_int256_565(memPos_3), memPos_3)) + return(memPos_3, sub(abi_encode_int256_555(memPos_3), memPos_3)) } } revert(0, 0) @@ -1514,7 +1505,7 @@ object \"D_72\" { { if slt(add(dataEnd, not(3)), 0) { revert(0, 0) } } - function abi_encode_int256_565(headStart) -> tail + function abi_encode_int256_555(headStart) -> tail { tail := add(headStart, 32) mstore(headStart, /** @src 0:124:126 \"41\" */ 0x29) @@ -1531,7 +1522,7 @@ object \"D_72\" { mstore(4, 0x11) revert(0, 0x24) } - function checked_add_int256_566(y) -> sum + function checked_add_int256_556(y) -> sum { if and(1, sgt(y, sub(shl(255, 1), 42))) { panic_error_0x11() } sum := add(/** @src 0:124:126 \"41\" */ 0x29, /** @src 1:91:166 \"contract D is C(3)...\" */ y) @@ -1553,13 +1544,6 @@ object \"D_72\" { let ret := add(_3, 1) sstore(_2, ret) /// @src 0:410:418 \"this.f()\" - if iszero(extcodesize(/** @src 0:410:414 \"this\" */ address())) - /// @src 0:410:418 \"this.f()\" - { - /// @src 1:91:166 \"contract D is C(3)...\" - revert(_2, _2) - } - /// @src 0:410:418 \"this.f()\" let _4 := /** @src 1:91:166 \"contract D is C(3)...\" */ mload(64) /// @src 0:410:418 \"this.f()\" mstore(_4, /** @src 1:91:166 \"contract D is C(3)...\" */ shl(228, 0x026121ff)) diff --git a/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol b/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol index ddd536a38..947f5cb23 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol @@ -61,9 +61,9 @@ contract C { // ---- // test_bytes() -> // gas irOptimized: 377545 -// gas legacy: 423563 +// gas legacy: 418955 // gas legacyOptimized: 331391 // test_uint256() -> // gas irOptimized: 528726 -// gas legacy: 591392 +// gas legacy: 586784 // gas legacyOptimized: 456137 diff --git a/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol b/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol index 8fe170e91..886d9dfd9 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol @@ -27,5 +27,5 @@ contract C { // library: L // f() -> 8, 7, 1, 2, 7, 12 // gas irOptimized: 167580 -// gas legacy: 169475 +// gas legacy: 169347 // gas legacyOptimized: 167397 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol index 3a4a23fef..f75eecfb5 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol @@ -62,9 +62,9 @@ contract C { // ---- // test_bytes() -> // gas irOptimized: 377545 -// gas legacy: 423563 +// gas legacy: 418955 // gas legacyOptimized: 331391 // test_uint256() -> // gas irOptimized: 528726 -// gas legacy: 591392 +// gas legacy: 586784 // gas legacyOptimized: 456137 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol index b730f3588..49b93cbbc 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol @@ -33,5 +33,5 @@ contract C is B { // ---- // test() -> 77 // gas irOptimized: 120044 -// gas legacy: 155221 +// gas legacy: 155093 // gas legacyOptimized: 111678 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol index 7832ef601..28658089a 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol @@ -41,4 +41,4 @@ contract C is B { // ---- // test() -> 5, 10 // gas irOptimized: 87578 -// gas legacy: 99137 +// gas legacy: 98881 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol b/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol index bf42f8776..131430aa5 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol @@ -22,5 +22,5 @@ contract C { // f(uint256[][1]): 32, 32, 1, 42 -> true // f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true // gas irOptimized: 172204 -// gas legacy: 141900 +// gas legacy: 141644 // gas legacyOptimized: 121788 diff --git a/test/libsolidity/semanticTests/arithmetics/check_var_init.sol b/test/libsolidity/semanticTests/arithmetics/check_var_init.sol index f8e4ca2a4..7e3edc127 100644 --- a/test/libsolidity/semanticTests/arithmetics/check_var_init.sol +++ b/test/libsolidity/semanticTests/arithmetics/check_var_init.sol @@ -18,4 +18,4 @@ contract D { // ---- // f() -> FAILURE, hex"4e487b71", 0x11 // g(), 100 wei -> 1 -// gas legacy: 101918 +// gas legacy: 101790 diff --git a/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol b/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol index 5e30621af..063e0bf9c 100644 --- a/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol +++ b/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol @@ -22,5 +22,5 @@ contract B { // ---- // f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004 // gas irOptimized: 130328 -// gas legacy: 235199 +// gas legacy: 234943 // gas legacyOptimized: 133119 diff --git a/test/libsolidity/semanticTests/array/function_array_cross_calls.sol b/test/libsolidity/semanticTests/array/function_array_cross_calls.sol index 95cb52f11..6edae7198 100644 --- a/test/libsolidity/semanticTests/array/function_array_cross_calls.sol +++ b/test/libsolidity/semanticTests/array/function_array_cross_calls.sol @@ -46,5 +46,5 @@ contract C { // ---- // test() -> 5, 6, 7 // gas irOptimized: 302321 -// gas legacy: 462080 +// gas legacy: 452172 // gas legacyOptimized: 294938 diff --git a/test/libsolidity/semanticTests/array/reusing_memory.sol b/test/libsolidity/semanticTests/array/reusing_memory.sol index 7d2b4d995..a8a534b92 100644 --- a/test/libsolidity/semanticTests/array/reusing_memory.sol +++ b/test/libsolidity/semanticTests/array/reusing_memory.sol @@ -27,5 +27,5 @@ contract Main { // ---- // f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1 // gas irOptimized: 113776 -// gas legacy: 126852 +// gas legacy: 126596 // gas legacyOptimized: 114079 diff --git a/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol b/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol index 63c2acbb5..7016e6c6e 100644 --- a/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol +++ b/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol @@ -27,5 +27,5 @@ contract Creator { // ---- // f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8 // gas irOptimized: 456873 -// gas legacy: 590939 +// gas legacy: 590683 // gas legacyOptimized: 448582 diff --git a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol index d4d41d80c..1aba4c7c4 100644 --- a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol +++ b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol @@ -27,5 +27,5 @@ contract Creator { // ---- // f(uint256,bytes): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> 7, "h" // gas irOptimized: 308702 -// gas legacy: 429173 +// gas legacy: 428917 // gas legacyOptimized: 298384 diff --git a/test/libsolidity/semanticTests/constructor/constructor_function_complex.sol b/test/libsolidity/semanticTests/constructor/constructor_function_complex.sol index 78466f3f0..f1043f559 100644 --- a/test/libsolidity/semanticTests/constructor/constructor_function_complex.sol +++ b/test/libsolidity/semanticTests/constructor/constructor_function_complex.sol @@ -19,4 +19,4 @@ contract C { // compileViaYul: also // ---- // f() -> 16 -// gas legacy: 103744 +// gas legacy: 103488 diff --git a/test/libsolidity/semanticTests/freeFunctions/new_operator.sol b/test/libsolidity/semanticTests/freeFunctions/new_operator.sol index 1694b64d5..0e89c7560 100644 --- a/test/libsolidity/semanticTests/freeFunctions/new_operator.sol +++ b/test/libsolidity/semanticTests/freeFunctions/new_operator.sol @@ -15,4 +15,4 @@ contract D { // compileViaYul: also // ---- // f() -> 2 -// gas legacy: 101754 +// gas legacy: 101626 diff --git a/test/libsolidity/semanticTests/functionCall/creation_function_call_no_args.sol b/test/libsolidity/semanticTests/functionCall/creation_function_call_no_args.sol index 8546c775e..0ab6fe0c3 100644 --- a/test/libsolidity/semanticTests/functionCall/creation_function_call_no_args.sol +++ b/test/libsolidity/semanticTests/functionCall/creation_function_call_no_args.sol @@ -13,4 +13,4 @@ contract D { // compileViaYul: also // ---- // f() -> 2 -// gas legacy: 101727 +// gas legacy: 101599 diff --git a/test/libsolidity/semanticTests/functionCall/failed_create.sol b/test/libsolidity/semanticTests/functionCall/failed_create.sol index b50890f55..49c6a80a9 100644 --- a/test/libsolidity/semanticTests/functionCall/failed_create.sol +++ b/test/libsolidity/semanticTests/functionCall/failed_create.sol @@ -19,7 +19,7 @@ contract C { // ---- // constructor(), 20 wei // gas irOptimized: 220113 -// gas legacy: 288299 +// gas legacy: 294569 // gas legacyOptimized: 177933 // f(uint256): 20 -> 1370859564726510389319704988634906228201275401179 // x() -> 1 @@ -27,7 +27,7 @@ contract C { // x() -> 1 // stack(uint256): 1023 -> FAILURE // gas irOptimized: 345821 -// gas legacy: 535367 +// gas legacy: 483942 // gas legacyOptimized: 354656 // x() -> 1 // stack(uint256): 10 -> 693016686122178122849713379390321835634789309880 diff --git a/test/libsolidity/semanticTests/functionTypes/store_function.sol b/test/libsolidity/semanticTests/functionTypes/store_function.sol index c2678a91d..9200bd120 100644 --- a/test/libsolidity/semanticTests/functionTypes/store_function.sol +++ b/test/libsolidity/semanticTests/functionTypes/store_function.sol @@ -29,5 +29,5 @@ contract C { // ---- // t() -> 9 // gas irOptimized: 99186 -// gas legacy: 159083 +// gas legacy: 158955 // gas legacyOptimized: 108916 diff --git a/test/libsolidity/semanticTests/immutable/multi_creation.sol b/test/libsolidity/semanticTests/immutable/multi_creation.sol index cd5992ce6..d4300cfe1 100644 --- a/test/libsolidity/semanticTests/immutable/multi_creation.sol +++ b/test/libsolidity/semanticTests/immutable/multi_creation.sol @@ -30,7 +30,7 @@ contract C { // ---- // f() -> 3, 7, 5 // gas irOptimized: 127592 -// gas legacy: 151590 +// gas legacy: 151334 // gas legacyOptimized: 125422 // x() -> 7 // y() -> 5 diff --git a/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol b/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol index 0dc9845f4..8c9c6195c 100644 --- a/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol +++ b/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol @@ -24,7 +24,7 @@ contract D { // ---- // f() -> 1 // gas irOptimized: 77164 -// gas legacy: 115012 +// gas legacy: 114884 // g() -> 5 // gas irOptimized: 77231 -// gas legacy: 115558 +// gas legacy: 115430 diff --git a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol index e012accaf..7322e5f96 100644 --- a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol +++ b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol @@ -26,4 +26,4 @@ contract B { // ---- // g() -> 42 // gas irOptimized: 80945 -// gas legacy: 125609 +// gas legacy: 125481 diff --git a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol index 4105577f0..9b5f9778c 100644 --- a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol +++ b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol @@ -26,5 +26,5 @@ contract B { // ---- // g() -> 42 // gas irOptimized: 111913 -// gas legacy: 185181 +// gas legacy: 185053 // gas legacyOptimized: 114726 diff --git a/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol b/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol index 9a095cc21..a400531ca 100644 --- a/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol +++ b/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol @@ -22,6 +22,6 @@ contract A { // compileViaYul: also // ---- // g(int256): -1 -> -1 -// gas legacy: 103622 +// gas legacy: 103494 // g(int256): 10 -> 10 -// gas legacy: 103250 +// gas legacy: 103122 diff --git a/test/libsolidity/semanticTests/interface_inheritance_conversions.sol b/test/libsolidity/semanticTests/interface_inheritance_conversions.sol index 11cb93832..5dfeb9a69 100644 --- a/test/libsolidity/semanticTests/interface_inheritance_conversions.sol +++ b/test/libsolidity/semanticTests/interface_inheritance_conversions.sol @@ -40,7 +40,7 @@ contract C { // gas irOptimized: 85640 // convertSubA() -> 1, 2 // gas irOptimized: 86395 -// gas legacy: 99303 +// gas legacy: 99047 // convertSubB() -> 1, 3 // gas irOptimized: 86338 -// gas legacy: 99237 +// gas legacy: 98981 diff --git a/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol b/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol index 17edaf3eb..2d1070e2a 100644 --- a/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol +++ b/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol @@ -23,5 +23,5 @@ contract A { // ---- // f(), 10 ether -> 3007, 3008, 3009 // gas irOptimized: 273275 -// gas legacy: 422885 +// gas legacy: 422501 // gas legacyOptimized: 287856 diff --git a/test/libsolidity/semanticTests/smoke/alignment.sol b/test/libsolidity/semanticTests/smoke/alignment.sol index 143473461..80c69bb43 100644 --- a/test/libsolidity/semanticTests/smoke/alignment.sol +++ b/test/libsolidity/semanticTests/smoke/alignment.sol @@ -27,5 +27,5 @@ contract D { // stateDecimal() -> right(42) // stateBytes() -> left(0x4200ef) // internalStateDecimal() -> 0x20 -// gas legacy: 101807 +// gas legacy: 101679 // update(bool,uint256,bytes32): false, -23, left(0x2300ef) -> false, -23, left(0x2300ef) diff --git a/test/libsolidity/semanticTests/various/code_access_content.sol b/test/libsolidity/semanticTests/various/code_access_content.sol index 3f8d56587..39ac71b54 100644 --- a/test/libsolidity/semanticTests/various/code_access_content.sol +++ b/test/libsolidity/semanticTests/various/code_access_content.sol @@ -42,4 +42,4 @@ contract C { // testRuntime() -> true // gas legacy: 101579 // testCreation() -> true -// gas legacy: 102137 +// gas legacy: 102009 diff --git a/test/libsolidity/semanticTests/various/code_access_create.sol b/test/libsolidity/semanticTests/various/code_access_create.sol index c32135fe5..ce0d6305d 100644 --- a/test/libsolidity/semanticTests/various/code_access_create.sol +++ b/test/libsolidity/semanticTests/various/code_access_create.sol @@ -26,4 +26,4 @@ contract C { // compileViaYul: also // ---- // test() -> 7 -// gas legacy: 102392 +// gas legacy: 102264 diff --git a/test/libsolidity/semanticTests/various/external_types_in_calls.sol b/test/libsolidity/semanticTests/various/external_types_in_calls.sol index 229e93fc1..1b50465b4 100644 --- a/test/libsolidity/semanticTests/various/external_types_in_calls.sol +++ b/test/libsolidity/semanticTests/various/external_types_in_calls.sol @@ -27,5 +27,5 @@ contract C { // compileViaYul: also // ---- // test() -> 9, 7 -// gas legacy: 130016 +// gas legacy: 129760 // t2() -> 9 diff --git a/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol b/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol index 8ef472136..25d7b3c78 100644 --- a/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol +++ b/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol @@ -23,5 +23,5 @@ contract C { // ---- // g() -> 2, 6 // gas irOptimized: 178953 -// gas legacy: 180890 +// gas legacy: 180762 // gas legacyOptimized: 179609 diff --git a/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol b/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol index ab6d6e59a..cc910826b 100644 --- a/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol +++ b/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol @@ -36,12 +36,12 @@ contract D { // compileViaYul: also // ---- // f() -> 0x1 # This should work, next should throw # -// gas legacy: 103844 +// gas legacy: 103716 // fview() -> FAILURE // gas irOptimized: 98438627 -// gas legacy: 98438803 +// gas legacy: 98438801 // gas legacyOptimized: 98438596 // fpure() -> FAILURE // gas irOptimized: 98438627 -// gas legacy: 98438803 +// gas legacy: 98438801 // gas legacyOptimized: 98438597 From 31c504c5baa24898f71790e42f4a626c15dca3a1 Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 28 Oct 2021 12:35:06 +0200 Subject: [PATCH 54/69] Add test for extcodesize check. --- .../external_call_at_construction_time.sol | 28 +++++++++++++ .../external_call_to_nonexisting.sol | 36 +++++++++++++++++ ...ernal_call_to_nonexisting_debugstrings.sol | 39 +++++++++++++++++++ .../precompile_extcodesize_check.sol | 11 +++++- 4 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 test/libsolidity/semanticTests/functionCall/external_call_at_construction_time.sol create mode 100644 test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol create mode 100644 test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol diff --git a/test/libsolidity/semanticTests/functionCall/external_call_at_construction_time.sol b/test/libsolidity/semanticTests/functionCall/external_call_at_construction_time.sol new file mode 100644 index 000000000..d5b0d0974 --- /dev/null +++ b/test/libsolidity/semanticTests/functionCall/external_call_at_construction_time.sol @@ -0,0 +1,28 @@ +pragma solidity >= 0.6.0; + +// This tests skipping the extcodesize check. + +contract T { + constructor() { this.f(); } + function f() external {} +} +contract U { + constructor() { this.f(); } + function f() external returns (uint) {} +} + +contract C { + function f(uint c) external returns (uint) { + if (c == 0) new T(); + else if (c == 1) new U(); + return 1 + c; + } +} + +// ==== +// EVMVersion: >=byzantium +// compileViaYul: also +// ---- +// f(uint256): 0 -> FAILURE +// f(uint256): 1 -> FAILURE +// f(uint256): 2 -> 3 diff --git a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol new file mode 100644 index 000000000..9546f1098 --- /dev/null +++ b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol @@ -0,0 +1,36 @@ +// This tests skipping the extcodesize check. + +interface I { + function a() external pure; + function b() external; + function c() external payable; + function x() external returns (uint); + function y() external returns (string memory); +} +contract C { + I i = I(address(0xcafecafe)); + constructor() payable {} + function f(uint c) external returns (uint) { + if (c == 0) i.a(); + else if (c == 1) i.b(); + else if (c == 2) i.c(); + else if (c == 3) i.c{value: 1}(); + else if (c == 4) i.x(); + else if (c == 5) i.y(); + return 1 + c; + } +} + +// ==== +// compileViaYul: also +// ---- +// constructor(), 1 ether -> +// gas legacy: 465314 +// gas legacyOptimized: 510004 +// f(uint256): 0 -> FAILURE +// f(uint256): 1 -> FAILURE +// f(uint256): 2 -> FAILURE +// f(uint256): 3 -> FAILURE +// f(uint256): 4 -> FAILURE +// f(uint256): 5 -> FAILURE +// f(uint256): 6 -> 7 diff --git a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol new file mode 100644 index 000000000..ca635d310 --- /dev/null +++ b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol @@ -0,0 +1,39 @@ +pragma solidity >= 0.6.0; + +// This tests skipping the extcodesize check. + +interface I { + function a() external pure; + function b() external; + function c() external payable; + function x() external returns (uint); + function y() external returns (string memory); +} +contract C { + I i = I(address(0xcafecafe)); + constructor() payable {} + function f(uint c) external returns (uint) { + if (c == 0) i.a(); + else if (c == 1) i.b(); + else if (c == 2) i.c(); + else if (c == 3) i.c{value: 1}(); + else if (c == 4) i.x(); + else if (c == 5) i.y(); + return 1 + c; + } +} + +// ==== +// EVMVersion: >=byzantium +// compileViaYul: also +// revertStrings: debug +// ---- +// constructor(), 1 ether -> +// gas legacyOptimized: 510004 +// f(uint256): 0 -> FAILURE, hex"08c379a0", 0x20, 37, "Target contract does not contain", " code" +// f(uint256): 1 -> FAILURE, hex"08c379a0", 0x20, 37, "Target contract does not contain", " code" +// f(uint256): 2 -> FAILURE, hex"08c379a0", 0x20, 37, "Target contract does not contain", " code" +// f(uint256): 3 -> FAILURE, hex"08c379a0", 0x20, 37, "Target contract does not contain", " code" +// f(uint256): 4 -> FAILURE, hex"08c379a0", 0x20, 37, "Target contract does not contain", " code" +// f(uint256): 5 -> FAILURE, hex"08c379a0", 0x20, 37, "Target contract does not contain", " code" +// f(uint256): 6 -> 7 diff --git a/test/libsolidity/semanticTests/functionCall/precompile_extcodesize_check.sol b/test/libsolidity/semanticTests/functionCall/precompile_extcodesize_check.sol index 7a9025e26..c07adb909 100644 --- a/test/libsolidity/semanticTests/functionCall/precompile_extcodesize_check.sol +++ b/test/libsolidity/semanticTests/functionCall/precompile_extcodesize_check.sol @@ -1,13 +1,21 @@ interface Identity { function selectorAndAppendValue(uint value) external pure returns (uint); } +interface ReturnMoreData { + function f(uint value) external pure returns (uint, uint, uint); +} contract C { Identity constant i = Identity(address(0x0004)); function testHighLevel() external pure returns (bool) { - // Should fail because `extcodesize(4) = 0` + // Works because the extcodesize check is skipped + // and the precompiled contract returns actual data. i.selectorAndAppendValue(5); return true; } + function testHighLevel2() external pure returns (uint, uint, uint) { + // Fails because the identity contract does not return enough data. + return ReturnMoreData(address(4)).f(2); + } function testLowLevel() external view returns (uint value) { (bool success, bytes memory ret) = address(4).staticcall( @@ -23,3 +31,4 @@ contract C { // ---- // testHighLevel() -> FAILURE // testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000 +// testHighLevel2() -> FAILURE From f320a95dd9be698df9fa7a3c12a7efc1a22a1521 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 2 Nov 2021 12:04:31 +0100 Subject: [PATCH 55/69] Update documentation. --- docs/control-structures.rst | 11 ++++++++++- docs/introduction-to-smart-contracts.rst | 21 +++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/docs/control-structures.rst b/docs/control-structures.rst index 49e66537d..84b65918d 100644 --- a/docs/control-structures.rst +++ b/docs/control-structures.rst @@ -114,10 +114,19 @@ otherwise, the ``value`` option would not be available. Due to the fact that the EVM considers a call to a non-existing contract to always succeed, Solidity uses the ``extcodesize`` opcode to check that the contract that is about to be called actually exists (it contains code) -and causes an exception if it does not. +and causes an exception if it does not. This check is skipped if the return +data will be decoded after the call and thus the ABI decoder will catch the +case of a non-existing contract. + Note that this check is not performed in case of :ref:`low-level calls ` which operate on addresses rather than contract instances. +.. note:: + Be careful when using high-level calls to + :ref:`precompiled contracts `, + since the compiler considers them non-existing according to the + above logic even though they execute code and can return data. + Function calls also cause exceptions if the called contract itself throws an exception or goes out of gas. diff --git a/docs/introduction-to-smart-contracts.rst b/docs/introduction-to-smart-contracts.rst index c22d4e6fa..d19a0decf 100644 --- a/docs/introduction-to-smart-contracts.rst +++ b/docs/introduction-to-smart-contracts.rst @@ -565,3 +565,24 @@ contracts, the Ether is forever lost. If you want to deactivate your contracts, you should instead **disable** them by changing some internal state which causes all functions to revert. This makes it impossible to use the contract, as it returns Ether immediately. + + +.. index:: ! precompiled contracts, ! precompiles, ! contract;precompiled + +.. _precompiledContracts: + +Precompiled Contracts +===================== + +There is a small set of contract addresses that are special: +The address range between ``1`` and (including) ``8`` contains +"precompiled contracts" that can be called as any other contract +but their behaviour (and their gas consumption) is not defined +by EVM code stored at that address (they do not contain code) +but instead is implemented in the EVM execution environment itself. + +Different EVM-compatible chains might use a different set of +precompiled contracts. It might also be possible that new +precompiled contracts are added to the Ethereum main chain in the future, +but you can reasonabyly expect them to always be in the range between +``1`` and ``0xffff`` (inclusive). \ No newline at end of file From 080c7245aebdb4e7ab1d2b2f3a6194244eda976f Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 4 Nov 2021 18:20:10 +0100 Subject: [PATCH 56/69] Update tests. --- .../output.json | 312 +++--------------- .../abi_encode_calldata_slice.sol | 8 +- .../struct/struct_storage_ptr.sol | 4 +- .../abi_encode_calldata_slice.sol | 8 +- ...2_in_function_inherited_in_v1_contract.sol | 4 +- ...ode_v2_in_modifier_used_in_v1_contract.sol | 2 +- .../abiEncoderV2/calldata_array.sol | 4 +- .../array/fixed_arrays_as_return_type.sol | 4 +- .../array/function_array_cross_calls.sol | 4 +- .../semanticTests/array/reusing_memory.sol | 4 +- .../constructor/arrays_in_constructors.sol | 4 +- .../bytes_in_constructors_packer.sol | 4 +- .../external_call_at_construction_time.sol | 2 - ...ernal_call_to_nonexisting_debugstrings.sol | 2 - .../functionCall/failed_create.sol | 8 +- .../precompile_extcodesize_check.sol | 4 +- .../functionTypes/store_function.sol | 4 +- .../immutable/multi_creation.sol | 4 +- .../address_overload_resolution.sol | 4 +- ...d_function_calldata_calldata_interface.sol | 2 +- ...ted_function_calldata_memory_interface.sol | 4 +- .../interface_inheritance_conversions.sol | 6 +- .../salted_create_with_value.sol | 4 +- .../skip_dynamic_types_for_structs.sol | 4 +- .../various/staticcall_for_view_and_pure.sol | 8 +- 25 files changed, 95 insertions(+), 323 deletions(-) diff --git a/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json b/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json index 773637b32..1c3999afc 100644 --- a/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json +++ b/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json @@ -285,40 +285,18 @@ sub_0: assembly { dup2 dup2 sstore - /* \"C\":403:407 this */ - address - /* \"C\":403:411 this.f() */ - extcodesize - tag_40 - jumpi - /* \"C\":79:428 contract C... */ - dup2 - dup3 - revert - /* \"C\":403:411 this.f() */ - tag_40: - /* \"C\":79:428 contract C... */ - /* \"C\":403:407 this */ - address - /* \"C\":403:411 this.f() */ - extcodesize - iszero - tag_43 - jumpi - /* \"C\":79:428 contract C... */ mload(0x40) shl(0xe4, 0x026121ff) /* \"C\":403:411 this.f() */ dup2 mstore 0x20 - /* \"C\":79:428 contract C... */ + /* \"C\":403:407 this */ dup2 /* \"C\":403:411 this.f() */ 0x04 - /* \"C\":79:428 contract C... */ - dup2 /* \"C\":403:407 this */ + dup2 address /* \"C\":403:411 this.f() */ gas @@ -326,55 +304,43 @@ sub_0: assembly { swap2 dup3 iszero - tag_45 + tag_43 jumpi dup1 - tag_41 - tag_40 swap3 - tag_47 + tag_45 jumpi /* \"C\":304:341 modifier m()... */ - tag_48: + tag_46: /* \"C\":392:411 stateVar + this.f() */ pop pop - tag_49 + tag_47 swap1 /* \"C\":392:422 stateVar + this.f() + immutVar */ - tag_50 + tag_48 /* \"C\":392:411 stateVar + this.f() */ swap3 tag_5 jump\t// in - tag_49: + tag_47: /* \"C\":414:422 immutVar */ immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") /* \"C\":392:422 stateVar + this.f() + immutVar */ swap1 tag_5 jump\t// in - tag_50: + tag_48: /* \"C\":304:341 modifier m()... */ swap1 jump\t// out /* \"C\":403:411 this.f() */ - tag_41: - tag_40: - tag_47: + tag_45: /* \"C\":79:428 contract C... */ swap1 swap2 pop /* \"C\":403:411 this.f() */ - dup2 - iszero - tag_42 - jumpi - dup2 - iszero - tag_41 - jumpi returndatasize /* \"C\":79:428 contract C... */ 0x1f @@ -391,73 +357,39 @@ sub_0: assembly { dup4 lt or - iszero - tag_43 - iszero - tag_42 - tag_51 + tag_49 jumpi pop swap2 /* \"C\":403:411 this.f() */ - tag_53 + tag_51 /* \"C\":392:411 stateVar + this.f() */ - tag_49 + tag_47 /* \"C\":79:428 contract C... */ swap3 /* \"C\":392:422 stateVar + this.f() + immutVar */ - tag_50 + tag_48 /* \"C\":79:428 contract C... */ - mstore - 0x24 - dup7 - revert - tag_43: - mstore - 0x24 - dup7 - revert - tag_42: swap5 0x40 mstore /* \"C\":403:411 this.f() */ - tag_44 - tag_43 returndatasize dup2 add swap1 tag_7 jump\t// in - tag_44: - swap1 - tag_43: - swap1 - tag_53: + tag_51: swap2 dup2 swap4 pop - tag_42: - /* \"C\":392:411 stateVar + this.f() */ - tag_45 - tag_41: - /* \"C\":392:411 stateVar + this.f() */ - tag_44 - jump(tag_48) + jump(tag_46) /* \"C\":79:428 contract C... */ - tag_51: + tag_49: shl(0xe0, 0x4e487b71) dup2 - dup6 - tag_5 - jump\t// in - tag_45: - dup6 - tag_5 - jump\t// in - tag_44: mstore 0x41 /* \"C\":403:411 this.f() */ @@ -475,53 +407,27 @@ sub_0: assembly { /* \"C\":79:428 contract C... */ revert /* \"C\":403:411 this.f() */ - tag_45: + tag_43: /* \"C\":79:428 contract C... */ swap4 pop pop pop - /* \"C\":392:422 stateVar + this.f() + immutVar */ - tag_46 - /* \"C\":414:422 immutVar */ - immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") - /* \"C\":392:422 stateVar + this.f() + immutVar */ - /* \"C\":392:422 stateVar + this.f() + immutVar */ - tag_45 - /* \"C\":414:422 immutVar */ - immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") - /* \"C\":392:422 stateVar + this.f() + immutVar */ pop mload(0x40) swap1 returndatasize swap1 dup3 - tag_5 - jump\t// in - tag_46: - /* \"C\":336:337 _ */ - tag_5 - jump\t// in - tag_45: - /* \"C\":336:337 _ */ returndatacopy returndatasize swap1 - revert - /* \"C\":403:411 this.f() */ - tag_43: - /* \"C\":79:428 contract C... */ - swap2 - pop - pop - dup1 revert tag_41: - tag_54 + tag_52 tag_3 jump\t// in - tag_54: + tag_52: jump(tag_42) tag_7: swap1 @@ -530,35 +436,17 @@ sub_0: assembly { swap2 sub slt - iszero - tag_48 - iszero - tag_47 - tag_55 + tag_53 jumpi mload swap1 jump\t// out - tag_55: + tag_53: pop pop 0x00 dup1 revert - tag_48: - pop - mload - swap2 - swap1 - pop - jump\t// out - tag_47: - pop - mload - swap2 - swap1 - pop - jump\t// out auxdata: } @@ -890,40 +778,18 @@ sub_0: assembly { dup2 dup2 sstore - /* \"C\":403:407 this */ - address - /* \"C\":403:411 this.f() */ - extcodesize - tag_40 - jumpi - /* \"D\":91:166 contract D is C(3)... */ - dup2 - dup3 - revert - /* \"C\":403:411 this.f() */ - tag_40: - /* \"D\":91:166 contract D is C(3)... */ - /* \"C\":403:407 this */ - address - /* \"C\":403:411 this.f() */ - extcodesize - iszero - tag_43 - jumpi - /* \"D\":91:166 contract D is C(3)... */ mload(0x40) shl(0xe4, 0x026121ff) /* \"C\":403:411 this.f() */ dup2 mstore 0x20 - /* \"D\":91:166 contract D is C(3)... */ + /* \"C\":403:407 this */ dup2 /* \"C\":403:411 this.f() */ 0x04 - /* \"D\":91:166 contract D is C(3)... */ - dup2 /* \"C\":403:407 this */ + dup2 address /* \"C\":403:411 this.f() */ gas @@ -931,55 +797,43 @@ sub_0: assembly { swap2 dup3 iszero - tag_45 + tag_43 jumpi dup1 - tag_41 - tag_40 swap3 - tag_47 + tag_45 jumpi /* \"C\":304:341 modifier m()... */ - tag_48: + tag_46: /* \"C\":392:411 stateVar + this.f() */ pop pop - tag_49 + tag_47 swap1 /* \"C\":392:422 stateVar + this.f() + immutVar */ - tag_50 + tag_48 /* \"C\":392:411 stateVar + this.f() */ swap3 tag_5 jump\t// in - tag_49: + tag_47: /* \"C\":414:422 immutVar */ immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") /* \"C\":392:422 stateVar + this.f() + immutVar */ swap1 tag_5 jump\t// in - tag_50: + tag_48: /* \"C\":304:341 modifier m()... */ swap1 jump\t// out /* \"C\":403:411 this.f() */ - tag_41: - tag_40: - tag_47: + tag_45: /* \"D\":91:166 contract D is C(3)... */ swap1 swap2 pop /* \"C\":403:411 this.f() */ - dup2 - iszero - tag_42 - jumpi - dup2 - iszero - tag_41 - jumpi returndatasize /* \"D\":91:166 contract D is C(3)... */ 0x1f @@ -996,73 +850,39 @@ sub_0: assembly { dup4 lt or - iszero - tag_43 - iszero - tag_42 - tag_51 + tag_49 jumpi pop swap2 /* \"C\":403:411 this.f() */ - tag_53 + tag_51 /* \"C\":392:411 stateVar + this.f() */ - tag_49 + tag_47 /* \"D\":91:166 contract D is C(3)... */ swap3 /* \"C\":392:422 stateVar + this.f() + immutVar */ - tag_50 + tag_48 /* \"D\":91:166 contract D is C(3)... */ - mstore - 0x24 - dup7 - revert - tag_43: - mstore - 0x24 - dup7 - revert - tag_42: swap5 0x40 mstore /* \"C\":403:411 this.f() */ - tag_44 - tag_43 returndatasize dup2 add swap1 tag_7 jump\t// in - tag_44: - swap1 - tag_43: - swap1 - tag_53: + tag_51: swap2 dup2 swap4 pop - tag_42: - /* \"C\":392:411 stateVar + this.f() */ - tag_45 - tag_41: - /* \"C\":392:411 stateVar + this.f() */ - tag_44 - jump(tag_48) + jump(tag_46) /* \"D\":91:166 contract D is C(3)... */ - tag_51: + tag_49: shl(0xe0, 0x4e487b71) dup2 - dup6 - tag_5 - jump\t// in - tag_45: - dup6 - tag_5 - jump\t// in - tag_44: mstore 0x41 /* \"C\":403:411 this.f() */ @@ -1080,21 +900,11 @@ sub_0: assembly { /* \"D\":91:166 contract D is C(3)... */ revert /* \"C\":403:411 this.f() */ - tag_45: + tag_43: /* \"D\":91:166 contract D is C(3)... */ swap4 pop pop - /* \"C\":392:422 stateVar + this.f() + immutVar */ - tag_46 - /* \"C\":414:422 immutVar */ - immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") - /* \"C\":392:422 stateVar + this.f() + immutVar */ - /* \"C\":392:422 stateVar + this.f() + immutVar */ - tag_45 - /* \"C\":414:422 immutVar */ - immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") - /* \"C\":392:422 stateVar + this.f() + immutVar */ pop pop mload(0x40) @@ -1102,31 +912,15 @@ sub_0: assembly { returndatasize swap1 dup3 - tag_5 - jump\t// in - tag_46: - /* \"C\":336:337 _ */ - tag_5 - jump\t// in - tag_45: - /* \"C\":336:337 _ */ returndatacopy returndatasize swap1 - revert - /* \"C\":403:411 this.f() */ - tag_43: - /* \"D\":91:166 contract D is C(3)... */ - swap2 - pop - pop - dup1 revert tag_41: - tag_54 + tag_52 tag_3 jump\t// in - tag_54: + tag_52: jump(tag_42) tag_7: swap1 @@ -1135,35 +929,17 @@ sub_0: assembly { swap2 sub slt - iszero - tag_48 - iszero - tag_47 - tag_55 + tag_53 jumpi mload swap1 jump\t// out - tag_55: + tag_53: pop pop 0x00 dup1 revert - tag_48: - pop - mload - swap2 - swap1 - pop - jump\t// out - tag_47: - pop - mload - swap2 - swap1 - pop - jump\t// out auxdata: } diff --git a/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol b/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol index 947f5cb23..e54c39d32 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol @@ -60,10 +60,10 @@ contract C { // compileViaYul: also // ---- // test_bytes() -> -// gas irOptimized: 377545 +// gas irOptimized: 373483 // gas legacy: 418955 -// gas legacyOptimized: 331391 +// gas legacyOptimized: 326783 // test_uint256() -> -// gas irOptimized: 528726 +// gas irOptimized: 524664 // gas legacy: 586784 -// gas legacyOptimized: 456137 +// gas legacyOptimized: 451529 diff --git a/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol b/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol index 886d9dfd9..19d9b1b9a 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol @@ -26,6 +26,6 @@ contract C { // ---- // library: L // f() -> 8, 7, 1, 2, 7, 12 -// gas irOptimized: 167580 +// gas irOptimized: 167446 // gas legacy: 169347 -// gas legacyOptimized: 167397 +// gas legacyOptimized: 167269 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol index f75eecfb5..53aeb8949 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol @@ -61,10 +61,10 @@ contract C { // compileViaYul: also // ---- // test_bytes() -> -// gas irOptimized: 377545 +// gas irOptimized: 373483 // gas legacy: 418955 -// gas legacyOptimized: 331391 +// gas legacyOptimized: 326783 // test_uint256() -> -// gas irOptimized: 528726 +// gas irOptimized: 524664 // gas legacy: 586784 -// gas legacyOptimized: 456137 +// gas legacyOptimized: 451529 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol index 49b93cbbc..953fa7945 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol @@ -32,6 +32,6 @@ contract C is B { // compileViaYul: also // ---- // test() -> 77 -// gas irOptimized: 120044 +// gas irOptimized: 119931 // gas legacy: 155093 -// gas legacyOptimized: 111678 +// gas legacyOptimized: 111550 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol index 28658089a..153118355 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol @@ -40,5 +40,5 @@ contract C is B { // compileViaYul: also // ---- // test() -> 5, 10 -// gas irOptimized: 87578 +// gas irOptimized: 87337 // gas legacy: 98881 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol b/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol index 131430aa5..11fccbb61 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol @@ -21,6 +21,6 @@ contract C { // f(uint256[][1]): 32, 32, 0 -> true // f(uint256[][1]): 32, 32, 1, 42 -> true // f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true -// gas irOptimized: 172204 +// gas irOptimized: 171964 // gas legacy: 141644 -// gas legacyOptimized: 121788 +// gas legacyOptimized: 121532 diff --git a/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol b/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol index 063e0bf9c..3b0a73d00 100644 --- a/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol +++ b/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol @@ -21,6 +21,6 @@ contract B { // compileViaYul: also // ---- // f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004 -// gas irOptimized: 130328 +// gas irOptimized: 130097 // gas legacy: 234943 -// gas legacyOptimized: 133119 +// gas legacyOptimized: 132863 diff --git a/test/libsolidity/semanticTests/array/function_array_cross_calls.sol b/test/libsolidity/semanticTests/array/function_array_cross_calls.sol index 6edae7198..9c78c1207 100644 --- a/test/libsolidity/semanticTests/array/function_array_cross_calls.sol +++ b/test/libsolidity/semanticTests/array/function_array_cross_calls.sol @@ -45,6 +45,6 @@ contract C { // compileViaYul: also // ---- // test() -> 5, 6, 7 -// gas irOptimized: 302321 +// gas irOptimized: 290947 // gas legacy: 452172 -// gas legacyOptimized: 294938 +// gas legacyOptimized: 285017 diff --git a/test/libsolidity/semanticTests/array/reusing_memory.sol b/test/libsolidity/semanticTests/array/reusing_memory.sol index a8a534b92..ee1a57b1e 100644 --- a/test/libsolidity/semanticTests/array/reusing_memory.sol +++ b/test/libsolidity/semanticTests/array/reusing_memory.sol @@ -26,6 +26,6 @@ contract Main { // compileViaYul: also // ---- // f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1 -// gas irOptimized: 113776 +// gas irOptimized: 113581 // gas legacy: 126596 -// gas legacyOptimized: 114079 +// gas legacyOptimized: 113823 diff --git a/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol b/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol index 7016e6c6e..7885b24a3 100644 --- a/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol +++ b/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol @@ -26,6 +26,6 @@ contract Creator { // compileViaYul: also // ---- // f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8 -// gas irOptimized: 456873 +// gas irOptimized: 456668 // gas legacy: 590683 -// gas legacyOptimized: 448582 +// gas legacyOptimized: 448326 diff --git a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol index 1aba4c7c4..434b926fc 100644 --- a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol +++ b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol @@ -26,6 +26,6 @@ contract Creator { // compileViaYul: also // ---- // f(uint256,bytes): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> 7, "h" -// gas irOptimized: 308702 +// gas irOptimized: 308497 // gas legacy: 428917 -// gas legacyOptimized: 298384 +// gas legacyOptimized: 298128 diff --git a/test/libsolidity/semanticTests/functionCall/external_call_at_construction_time.sol b/test/libsolidity/semanticTests/functionCall/external_call_at_construction_time.sol index d5b0d0974..2fb2f266d 100644 --- a/test/libsolidity/semanticTests/functionCall/external_call_at_construction_time.sol +++ b/test/libsolidity/semanticTests/functionCall/external_call_at_construction_time.sol @@ -1,5 +1,3 @@ -pragma solidity >= 0.6.0; - // This tests skipping the extcodesize check. contract T { diff --git a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol index ca635d310..f426e628e 100644 --- a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol +++ b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol @@ -1,5 +1,3 @@ -pragma solidity >= 0.6.0; - // This tests skipping the extcodesize check. interface I { diff --git a/test/libsolidity/semanticTests/functionCall/failed_create.sol b/test/libsolidity/semanticTests/functionCall/failed_create.sol index 49c6a80a9..54cd9f06a 100644 --- a/test/libsolidity/semanticTests/functionCall/failed_create.sol +++ b/test/libsolidity/semanticTests/functionCall/failed_create.sol @@ -18,17 +18,17 @@ contract C { // compileViaYul: also // ---- // constructor(), 20 wei -// gas irOptimized: 220113 +// gas irOptimized: 218775 // gas legacy: 294569 -// gas legacyOptimized: 177933 +// gas legacyOptimized: 174699 // f(uint256): 20 -> 1370859564726510389319704988634906228201275401179 // x() -> 1 // f(uint256): 20 -> FAILURE // x() -> 1 // stack(uint256): 1023 -> FAILURE -// gas irOptimized: 345821 +// gas irOptimized: 296769 // gas legacy: 483942 -// gas legacyOptimized: 354656 +// gas legacyOptimized: 298807 // x() -> 1 // stack(uint256): 10 -> 693016686122178122849713379390321835634789309880 // x() -> 2 diff --git a/test/libsolidity/semanticTests/functionCall/precompile_extcodesize_check.sol b/test/libsolidity/semanticTests/functionCall/precompile_extcodesize_check.sol index c07adb909..b82c5f9b7 100644 --- a/test/libsolidity/semanticTests/functionCall/precompile_extcodesize_check.sol +++ b/test/libsolidity/semanticTests/functionCall/precompile_extcodesize_check.sol @@ -26,9 +26,9 @@ contract C { } // ==== -// compileViaYul: also // EVMVersion: >=constantinople +// compileViaYul: also // ---- -// testHighLevel() -> FAILURE +// testHighLevel() -> true // testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000 // testHighLevel2() -> FAILURE diff --git a/test/libsolidity/semanticTests/functionTypes/store_function.sol b/test/libsolidity/semanticTests/functionTypes/store_function.sol index 9200bd120..dab82918a 100644 --- a/test/libsolidity/semanticTests/functionTypes/store_function.sol +++ b/test/libsolidity/semanticTests/functionTypes/store_function.sol @@ -28,6 +28,6 @@ contract C { // compileViaYul: also // ---- // t() -> 9 -// gas irOptimized: 99186 +// gas irOptimized: 99064 // gas legacy: 158955 -// gas legacyOptimized: 108916 +// gas legacyOptimized: 108788 diff --git a/test/libsolidity/semanticTests/immutable/multi_creation.sol b/test/libsolidity/semanticTests/immutable/multi_creation.sol index d4300cfe1..2f74c17f5 100644 --- a/test/libsolidity/semanticTests/immutable/multi_creation.sol +++ b/test/libsolidity/semanticTests/immutable/multi_creation.sol @@ -29,8 +29,8 @@ contract C { // compileViaYul: also // ---- // f() -> 3, 7, 5 -// gas irOptimized: 127592 +// gas irOptimized: 127387 // gas legacy: 151334 -// gas legacyOptimized: 125422 +// gas legacyOptimized: 125166 // x() -> 7 // y() -> 5 diff --git a/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol b/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol index 8c9c6195c..6a9ff7c31 100644 --- a/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol +++ b/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol @@ -23,8 +23,8 @@ contract D { // compileViaYul: also // ---- // f() -> 1 -// gas irOptimized: 77164 +// gas irOptimized: 77051 // gas legacy: 114884 // g() -> 5 -// gas irOptimized: 77231 +// gas irOptimized: 77106 // gas legacy: 115430 diff --git a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol index 7322e5f96..ed28477b2 100644 --- a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol +++ b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol @@ -25,5 +25,5 @@ contract B { // compileViaYul: also // ---- // g() -> 42 -// gas irOptimized: 80945 +// gas irOptimized: 80813 // gas legacy: 125481 diff --git a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol index 9b5f9778c..46992694e 100644 --- a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol +++ b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol @@ -25,6 +25,6 @@ contract B { // compileViaYul: also // ---- // g() -> 42 -// gas irOptimized: 111913 +// gas irOptimized: 111781 // gas legacy: 185053 -// gas legacyOptimized: 114726 +// gas legacyOptimized: 114598 diff --git a/test/libsolidity/semanticTests/interface_inheritance_conversions.sol b/test/libsolidity/semanticTests/interface_inheritance_conversions.sol index 5dfeb9a69..95f831e24 100644 --- a/test/libsolidity/semanticTests/interface_inheritance_conversions.sol +++ b/test/libsolidity/semanticTests/interface_inheritance_conversions.sol @@ -37,10 +37,10 @@ contract C { // compileViaYul: also // ---- // convertParent() -> 1 -// gas irOptimized: 85640 +// gas irOptimized: 85524 // convertSubA() -> 1, 2 -// gas irOptimized: 86395 +// gas irOptimized: 86155 // gas legacy: 99047 // convertSubB() -> 1, 3 -// gas irOptimized: 86338 +// gas irOptimized: 86098 // gas legacy: 98981 diff --git a/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol b/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol index 2d1070e2a..e8fe01687 100644 --- a/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol +++ b/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol @@ -22,6 +22,6 @@ contract A { // compileViaYul: also // ---- // f(), 10 ether -> 3007, 3008, 3009 -// gas irOptimized: 273275 +// gas irOptimized: 272947 // gas legacy: 422501 -// gas legacyOptimized: 287856 +// gas legacyOptimized: 287472 diff --git a/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol b/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol index 25d7b3c78..cad181c8f 100644 --- a/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol +++ b/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol @@ -22,6 +22,6 @@ contract C { // compileViaYul: also // ---- // g() -> 2, 6 -// gas irOptimized: 178953 +// gas irOptimized: 178835 // gas legacy: 180762 -// gas legacyOptimized: 179609 +// gas legacyOptimized: 179481 diff --git a/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol b/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol index cc910826b..1950f7a4d 100644 --- a/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol +++ b/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol @@ -38,10 +38,10 @@ contract D { // f() -> 0x1 # This should work, next should throw # // gas legacy: 103716 // fview() -> FAILURE -// gas irOptimized: 98438627 +// gas irOptimized: 98438625 // gas legacy: 98438801 -// gas legacyOptimized: 98438596 +// gas legacyOptimized: 98438594 // fpure() -> FAILURE -// gas irOptimized: 98438627 +// gas irOptimized: 98438626 // gas legacy: 98438801 -// gas legacyOptimized: 98438597 +// gas legacyOptimized: 98438595 From ed907561ebe51be903d8e76742b7b7b93901b489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 25 Oct 2021 14:30:15 +0200 Subject: [PATCH 57/69] externalTests: Enable `set -e` in external tests --- test/externalTests/colony.sh | 3 +++ test/externalTests/ens.sh | 3 +++ test/externalTests/gnosis-v2.sh | 3 +++ test/externalTests/gnosis.sh | 3 +++ test/externalTests/solc-js/solc-js.sh | 3 +++ test/externalTests/zeppelin.sh | 3 +++ 6 files changed, 18 insertions(+) diff --git a/test/externalTests/colony.sh b/test/externalTests/colony.sh index c807f9022..ef06f1d7b 100755 --- a/test/externalTests/colony.sh +++ b/test/externalTests/colony.sh @@ -18,6 +18,9 @@ # # (c) 2019 solidity contributors. #------------------------------------------------------------------------------ + +set -e + source scripts/common.sh source test/externalTests/common.sh diff --git a/test/externalTests/ens.sh b/test/externalTests/ens.sh index 90c96d5a5..e3bdb229a 100755 --- a/test/externalTests/ens.sh +++ b/test/externalTests/ens.sh @@ -18,6 +18,9 @@ # # (c) 2019 solidity contributors. #------------------------------------------------------------------------------ + +set -e + source scripts/common.sh source test/externalTests/common.sh diff --git a/test/externalTests/gnosis-v2.sh b/test/externalTests/gnosis-v2.sh index 19ff3edcb..338b2418f 100755 --- a/test/externalTests/gnosis-v2.sh +++ b/test/externalTests/gnosis-v2.sh @@ -18,6 +18,9 @@ # # (c) 2020 solidity contributors. #------------------------------------------------------------------------------ + +set -e + source scripts/common.sh source test/externalTests/common.sh diff --git a/test/externalTests/gnosis.sh b/test/externalTests/gnosis.sh index f8ca999d6..a8a50782d 100755 --- a/test/externalTests/gnosis.sh +++ b/test/externalTests/gnosis.sh @@ -18,6 +18,9 @@ # # (c) 2019 solidity contributors. #------------------------------------------------------------------------------ + +set -e + source scripts/common.sh source test/externalTests/common.sh diff --git a/test/externalTests/solc-js/solc-js.sh b/test/externalTests/solc-js/solc-js.sh index 3762ba7a2..fa0d7ccee 100755 --- a/test/externalTests/solc-js/solc-js.sh +++ b/test/externalTests/solc-js/solc-js.sh @@ -18,6 +18,9 @@ # # (c) 2019 solidity contributors. #------------------------------------------------------------------------------ + +set -e + source scripts/common.sh source test/externalTests/common.sh diff --git a/test/externalTests/zeppelin.sh b/test/externalTests/zeppelin.sh index 97da3d47b..ca90d46f4 100755 --- a/test/externalTests/zeppelin.sh +++ b/test/externalTests/zeppelin.sh @@ -18,6 +18,9 @@ # # (c) 2019 solidity contributors. #------------------------------------------------------------------------------ + +set -e + source scripts/common.sh source test/externalTests/common.sh From bc2402e76f94cf4ec343d4873adc1485b9ccd720 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 26 Oct 2021 12:50:30 +0200 Subject: [PATCH 58/69] externalTests: Use named tmp dirs --- test/externalTests/common.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/externalTests/common.sh b/test/externalTests/common.sh index bc24cd1d1..f015b5fd7 100644 --- a/test/externalTests/common.sh +++ b/test/externalTests/common.sh @@ -251,7 +251,7 @@ function external_test printTask "Testing $name..." echo "===========================" - DIR=$(mktemp -d) + DIR=$(mktemp -d -t "ext-test-${name}-XXXXXX") ( if [ -z "$main_fn" ]; then printError "Test main function not defined." From fc224f74c7fbff547714a59470fab0d2b1410168 Mon Sep 17 00:00:00 2001 From: Marenz Date: Thu, 28 Oct 2021 15:30:31 +0200 Subject: [PATCH 59/69] Evaluate absolute paths for imports in 'parsing' stage --- Changelog.md | 1 + libsolidity/interface/CompilerStack.cpp | 26 ++++--- libsolidity/interface/CompilerStack.h | 4 +- .../args | 1 + .../input.json | 12 ++++ .../output.json | 67 +++++++++++++++++++ .../not_existing_import_parseOnly.json | 1 + 7 files changed, 101 insertions(+), 11 deletions(-) create mode 100644 test/cmdlineTests/standard_parsing_import_absolute_paths/args create mode 100644 test/cmdlineTests/standard_parsing_import_absolute_paths/input.json create mode 100644 test/cmdlineTests/standard_parsing_import_absolute_paths/output.json diff --git a/Changelog.md b/Changelog.md index ff183e22b..aad7b2a53 100644 --- a/Changelog.md +++ b/Changelog.md @@ -8,6 +8,7 @@ Compiler Features: * Commandline Interface: Accept nested brackets in step sequences passed to ``--yul-optimizations``. * Commandline Interface: Add ``--debug-info`` option for selecting how much extra debug information should be included in the produced EVM assembly and Yul code. * Commandline Interface: Use different colors when printing errors, warnings and infos. + * JSON AST: Set absolute paths of imports earlier, in the ``parsing`` stage. * SMTChecker: Output values for ``block.*``, ``msg.*`` and ``tx.*`` variables that are present in the called functions. * 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``. * Standard JSON: Accept nested brackets in step sequences passed to ``settings.optimizer.details.yulDetails.optimizerSteps``. diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 9fa3cb164..27e0f9d3a 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -350,8 +350,22 @@ bool CompilerStack::parse() else { source.ast->annotation().path = path; + + for (auto const& import: ASTNode::filteredNodes(source.ast->nodes())) + { + solAssert(!import->path().empty(), "Import path cannot be empty."); + + // The current value of `path` is the absolute path as seen from this source file. + // We first have to apply remappings before we can store the actual absolute path + // as seen globally. + import->annotation().absolutePath = applyRemapping(util::absolutePath( + import->path(), + path + ), path); + } + if (m_stopAfter >= ParsedAndImported) - for (auto const& newSource: loadMissingSources(*source.ast, path)) + for (auto const& newSource: loadMissingSources(*source.ast)) { string const& newPath = newSource.first; string const& newContents = newSource.second; @@ -1091,7 +1105,7 @@ string const& CompilerStack::Source::ipfsUrl() const return ipfsUrlCached; } -StringMap CompilerStack::loadMissingSources(SourceUnit const& _ast, std::string const& _sourcePath) +StringMap CompilerStack::loadMissingSources(SourceUnit const& _ast) { solAssert(m_stackState < ParsedAndImported, ""); StringMap newSources; @@ -1100,14 +1114,8 @@ StringMap CompilerStack::loadMissingSources(SourceUnit const& _ast, std::string for (auto const& node: _ast.nodes()) if (ImportDirective const* import = dynamic_cast(node.get())) { - solAssert(!import->path().empty(), "Import path cannot be empty."); + string const& importPath = *import->annotation().absolutePath; - string importPath = util::absolutePath(import->path(), _sourcePath); - // The current value of `path` is the absolute path as seen from this source file. - // We first have to apply remappings before we can store the actual absolute path - // as seen globally. - importPath = applyRemapping(importPath, _sourcePath); - import->annotation().absolutePath = importPath; if (m_sources.count(importPath) || newSources.count(importPath)) continue; diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index c97581a65..3609662e0 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -392,9 +392,9 @@ private: void findAndReportCyclicContractDependencies(); /// Loads the missing sources from @a _ast (named @a _path) using the callback - /// @a m_readFile and stores the absolute paths of all imports in the AST annotations. + /// @a m_readFile /// @returns the newly loaded sources. - StringMap loadMissingSources(SourceUnit const& _ast, std::string const& _path); + StringMap loadMissingSources(SourceUnit const& _ast); std::string applyRemapping(std::string const& _path, std::string const& _context); void resolveImports(); diff --git a/test/cmdlineTests/standard_parsing_import_absolute_paths/args b/test/cmdlineTests/standard_parsing_import_absolute_paths/args new file mode 100644 index 000000000..a905f1fe6 --- /dev/null +++ b/test/cmdlineTests/standard_parsing_import_absolute_paths/args @@ -0,0 +1 @@ +--pretty-json --json-indent 4 diff --git a/test/cmdlineTests/standard_parsing_import_absolute_paths/input.json b/test/cmdlineTests/standard_parsing_import_absolute_paths/input.json new file mode 100644 index 000000000..9ec5150b4 --- /dev/null +++ b/test/cmdlineTests/standard_parsing_import_absolute_paths/input.json @@ -0,0 +1,12 @@ +{ + "language": "Solidity", + "sources": { + "/project/../C.sol": {"content": "//SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\nimport \"../L.sol\";"}, + "/lib/L.sol": {"content": "//SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\n"} + }, + "settings": { + "stopAfter": "parsing", + "remappings": [":/project/=/lib/"], + "outputSelection": {"*": {"": ["ast"]}} + } +} diff --git a/test/cmdlineTests/standard_parsing_import_absolute_paths/output.json b/test/cmdlineTests/standard_parsing_import_absolute_paths/output.json new file mode 100644 index 000000000..1982561ef --- /dev/null +++ b/test/cmdlineTests/standard_parsing_import_absolute_paths/output.json @@ -0,0 +1,67 @@ +{ + "sources": + { + "/lib/L.sol": + { + "ast": + { + "absolutePath": "/lib/L.sol", + "id": 2, + "license": "GPL-2.0", + "nodeType": "SourceUnit", + "nodes": + [ + { + "id": 1, + "literals": + [ + "solidity", + ">=", + "0.0" + ], + "nodeType": "PragmaDirective", + "src": "35:22:0" + } + ], + "src": "35:23:0" + }, + "id": 0 + }, + "/project/../C.sol": + { + "ast": + { + "absolutePath": "/project/../C.sol", + "id": 5, + "license": "GPL-2.0", + "nodeType": "SourceUnit", + "nodes": + [ + { + "id": 3, + "literals": + [ + "solidity", + ">=", + "0.0" + ], + "nodeType": "PragmaDirective", + "src": "35:22:1" + }, + { + "absolutePath": "/lib/L.sol", + "file": "../L.sol", + "id": 4, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "src": "58:18:1", + "symbolAliases": [], + "unitAlias": "" + } + ], + "src": "35:41:1" + }, + "id": 1 + } + } +} diff --git a/test/libsolidity/ASTJSON/not_existing_import_parseOnly.json b/test/libsolidity/ASTJSON/not_existing_import_parseOnly.json index a42a10aed..a36c59fff 100644 --- a/test/libsolidity/ASTJSON/not_existing_import_parseOnly.json +++ b/test/libsolidity/ASTJSON/not_existing_import_parseOnly.json @@ -5,6 +5,7 @@ "nodes": [ { + "absolutePath": "notexisting.sol", "file": "notexisting.sol", "id": 1, "nameLocation": "28:11:1", From 7ccdbd5b08e51b43eef791f0495fee215bc0c791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 28 Oct 2021 11:58:47 +0200 Subject: [PATCH 60/69] Use consistent syntax for Bash function declarations --- scripts/check_style.sh | 2 +- scripts/ci/build_ossfuzz.sh | 4 ++-- scripts/ci/docker_upgrade.sh | 6 +++-- scripts/common.sh | 24 +++++++++---------- scripts/common_cmdline.sh | 3 ++- scripts/docker_deploy_manual.sh | 2 +- scripts/docs_version_pragma_check.sh | 8 +++---- .../bytecode_reports_for_modified_binaries.sh | 6 ++--- scripts/soltest.sh | 3 ++- scripts/test_antlr_grammar.sh | 6 ++--- scripts/tests.sh | 3 ++- .../docker-scripts/rebuild_tags.sh | 9 ++++--- scripts/yul_coverage.sh | 6 +++-- test/cmdlineTests.sh | 4 ++-- test/docsCodeStyle.sh | 8 +++---- test/externalTests/common.sh | 6 +++-- test/stopAfterParseTests.sh | 2 +- 17 files changed, 57 insertions(+), 45 deletions(-) diff --git a/scripts/check_style.sh b/scripts/check_style.sh index 78b0aa23c..601981b5c 100755 --- a/scripts/check_style.sh +++ b/scripts/check_style.sh @@ -35,7 +35,7 @@ then exit 1 fi -function preparedGrep() +function preparedGrep { git grep -nIE "$1" -- '*.h' '*.cpp' | grep -v "${EXCLUDE_FILES_JOINED}" return $? diff --git a/scripts/ci/build_ossfuzz.sh b/scripts/ci/build_ossfuzz.sh index f208c9b7f..1240b6877 100755 --- a/scripts/ci/build_ossfuzz.sh +++ b/scripts/ci/build_ossfuzz.sh @@ -5,7 +5,7 @@ ROOTDIR="/root/project" BUILDDIR="${ROOTDIR}/build" mkdir -p "${BUILDDIR}" && mkdir -p "$BUILDDIR/deps" -generate_protobuf_bindings() +function generate_protobuf_bindings { cd "${ROOTDIR}"/test/tools/ossfuzz # Generate protobuf C++ bindings @@ -15,7 +15,7 @@ generate_protobuf_bindings() done } -build_fuzzers() +function build_fuzzers { cd "${BUILDDIR}" cmake .. -DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE:-Release}" \ diff --git a/scripts/ci/docker_upgrade.sh b/scripts/ci/docker_upgrade.sh index 29e80354a..a9c7acaf2 100755 --- a/scripts/ci/docker_upgrade.sh +++ b/scripts/ci/docker_upgrade.sh @@ -1,11 +1,13 @@ #!/usr/bin/env bash set -e -function error() { +function error +{ echo >&2 "ERROR: ${1} Aborting." && false } -function warning() { +function warning +{ echo >&2 "WARNING: ${1}" } diff --git a/scripts/common.sh b/scripts/common.sh index 6d9b0a3ba..3e40754a6 100644 --- a/scripts/common.sh +++ b/scripts/common.sh @@ -29,15 +29,15 @@ _initial_work_dir=$(pwd) if [ "$CIRCLECI" ] then export TERM="${TERM:-xterm}" - function printTask() { echo "$(tput bold)$(tput setaf 2)$1$(tput setaf 7)"; } - function printError() { >&2 echo "$(tput setaf 1)$1$(tput setaf 7)"; } - function printWarning() { >&2 echo "$(tput setaf 11)$1$(tput setaf 7)"; } - function printLog() { echo "$(tput setaf 3)$1$(tput setaf 7)"; } + function printTask { echo "$(tput bold)$(tput setaf 2)$1$(tput setaf 7)"; } + function printError { >&2 echo "$(tput setaf 1)$1$(tput setaf 7)"; } + function printWarning { >&2 echo "$(tput setaf 11)$1$(tput setaf 7)"; } + function printLog { echo "$(tput setaf 3)$1$(tput setaf 7)"; } else - function printTask() { echo "$(tput bold)$(tput setaf 2)$1$(tput sgr0)"; } - function printError() { >&2 echo "$(tput setaf 1)$1$(tput sgr0)"; } - function printWarning() { >&2 echo "$(tput setaf 11)$1$(tput sgr0)"; } - function printLog() { echo "$(tput setaf 3)$1$(tput sgr0)"; } + function printTask { echo "$(tput bold)$(tput setaf 2)$1$(tput sgr0)"; } + function printError { >&2 echo "$(tput setaf 1)$1$(tput sgr0)"; } + function printWarning { >&2 echo "$(tput setaf 11)$1$(tput sgr0)"; } + function printLog { echo "$(tput setaf 3)$1$(tput sgr0)"; } fi function printStackTrace @@ -78,7 +78,7 @@ function printStackTrace done } -function fail() +function fail { printError "$@" @@ -86,7 +86,7 @@ function fail() return 1 } -function assertFail() +function assertFail { printError "" (( $# == 0 )) && printError "Assertion failed." @@ -97,7 +97,7 @@ function assertFail() exit 2 } -function msg_on_error() +function msg_on_error { local error_message local no_stdout=false @@ -171,7 +171,7 @@ function msg_on_error() fi } -safe_kill() +function safe_kill { local PID=${1} local NAME=${2:-${1}} diff --git a/scripts/common_cmdline.sh b/scripts/common_cmdline.sh index 15d93f562..3efeadc03 100644 --- a/scripts/common_cmdline.sh +++ b/scripts/common_cmdline.sh @@ -22,7 +22,8 @@ YULARGS=(--strict-assembly) FULLARGS=(--optimize --combined-json "abi,asm,ast,bin,bin-runtime,devdoc,hashes,metadata,opcodes,srcmap,srcmap-runtime,userdoc") OLDARGS=(--optimize --combined-json "abi,asm,ast,bin,bin-runtime,devdoc,interface,metadata,opcodes,srcmap,srcmap-runtime,userdoc") -function compileFull() + +function compileFull { local expected_exit_code=0 local expect_output='none' diff --git a/scripts/docker_deploy_manual.sh b/scripts/docker_deploy_manual.sh index 18d2228d0..12d3e5ff4 100755 --- a/scripts/docker_deploy_manual.sh +++ b/scripts/docker_deploy_manual.sh @@ -28,7 +28,7 @@ else date -u +"nightly.%Y.%-m.%-d" > prerelease.txt fi -tag_and_push() +function tag_and_push { docker tag "$image:$1" "$image:$2" docker push "$image:$2" diff --git a/scripts/docs_version_pragma_check.sh b/scripts/docs_version_pragma_check.sh index d16645da8..d56bed3a1 100755 --- a/scripts/docs_version_pragma_check.sh +++ b/scripts/docs_version_pragma_check.sh @@ -36,7 +36,7 @@ source "${REPO_ROOT}/scripts/common_cmdline.sh" developmentVersion=$("$REPO_ROOT/scripts/get_version.sh") -function versionGreater() +function versionGreater { v1=$1 v2=$2 @@ -58,7 +58,7 @@ function versionGreater() return 1 } -function versionEqual() +function versionEqual { if [[ "$1" == "$2" ]] then @@ -67,7 +67,7 @@ function versionEqual() return 1 } -function getAllAvailableVersions() +function getAllAvailableVersions { allVersions=() local allListedVersions @@ -85,7 +85,7 @@ function getAllAvailableVersions() done } -function findMinimalVersion() +function findMinimalVersion { local f=$1 local greater=false diff --git a/scripts/solc-bin/bytecode_reports_for_modified_binaries.sh b/scripts/solc-bin/bytecode_reports_for_modified_binaries.sh index 3401c127f..69d6a34d0 100755 --- a/scripts/solc-bin/bytecode_reports_for_modified_binaries.sh +++ b/scripts/solc-bin/bytecode_reports_for_modified_binaries.sh @@ -50,14 +50,14 @@ # FIXME: Can't use set -u because the old Bash on macOS treats empty arrays as unbound variables set -eo pipefail -die() +function die { # shellcheck disable=SC2059 >&2 printf "ERROR: $1\n" "${@:2}" exit 1 } -get_reported_solc_version() +function get_reported_solc_version { local solc_binary="$1" @@ -70,7 +70,7 @@ get_reported_solc_version() echo "$version_banner" | tail -n 1 | sed -n -E 's/^Version: (.*)$/\1/p' } -validate_reported_version() +function validate_reported_version { local reported_version="$1" local expected_version_and_commit="$2" diff --git a/scripts/soltest.sh b/scripts/soltest.sh index e9b6de979..e15aeb9bf 100755 --- a/scripts/soltest.sh +++ b/scripts/soltest.sh @@ -8,7 +8,8 @@ BOOST_OPTIONS=() SOLTEST_OPTIONS=() SOLIDITY_BUILD_DIR=${SOLIDITY_BUILD_DIR:-${REPO_ROOT}/build} -usage() { +function usage +{ echo 2>&1 " Usage: $0 [options] [soltest-options] Runs BOOST C++ unit test program, soltest. diff --git a/scripts/test_antlr_grammar.sh b/scripts/test_antlr_grammar.sh index 97aaa3b93..5745f01be 100755 --- a/scripts/test_antlr_grammar.sh +++ b/scripts/test_antlr_grammar.sh @@ -20,7 +20,7 @@ SGR_BLUE="\033[34m" vt_cursor_up() { echo -ne "\033[A"; } vt_cursor_begin_of_line() { echo -ne "\r"; } -download_antlr4() +function download_antlr4 { if [[ ! -e "$ANTLR_JAR" ]] then @@ -28,7 +28,7 @@ download_antlr4() fi } -prepare_workdir() +function prepare_workdir { mkdir -p "${ROOT_DIR}/build/deps" mkdir -p "${WORKDIR}" @@ -51,7 +51,7 @@ javac -classpath "${ANTLR_JAR}" "${WORKDIR}/src/"*.java -d "${WORKDIR}/target/" # Run tests failed_count=0 -test_file() +function test_file { local SOL_FILE SOL_FILE="$(${READLINK} -m "${1}")" diff --git a/scripts/tests.sh b/scripts/tests.sh index 964d00668..029be1629 100755 --- a/scripts/tests.sh +++ b/scripts/tests.sh @@ -38,7 +38,8 @@ source "${REPO_ROOT}/scripts/common.sh" WORKDIR=$(mktemp -d) CMDLINE_PID= -cleanup() { +function cleanup +{ # ensure failing commands don't cause termination during cleanup (especially within safe_kill) set +e diff --git a/scripts/wasm-rebuild/docker-scripts/rebuild_tags.sh b/scripts/wasm-rebuild/docker-scripts/rebuild_tags.sh index 18c922c06..eaca0c730 100755 --- a/scripts/wasm-rebuild/docker-scripts/rebuild_tags.sh +++ b/scripts/wasm-rebuild/docker-scripts/rebuild_tags.sh @@ -38,7 +38,8 @@ ORANGE='\033[0;33m' CYAN='\033[0;36m' RESET='\033[0m' -function generate_bytecode_report() { +function generate_bytecode_report +{ rm -rf /tmp/report.txt local EXIT_STATUS @@ -74,7 +75,8 @@ function generate_bytecode_report() { echo -e "${RED}FAILURE${RESET}" fi } -function clean_git_checkout() { +function clean_git_checkout +{ git submodule deinit --all -q git reset --hard HEAD --quiet git clean -f -d -x --quiet @@ -82,7 +84,8 @@ function clean_git_checkout() { git submodule init -q git submodule update -q } -function process_tag() { +function process_tag +{ local TAG=$1 cd /src # Checkout the historic commit instead of the tag directly. diff --git a/scripts/yul_coverage.sh b/scripts/yul_coverage.sh index 02b9a0476..b2b16675c 100755 --- a/scripts/yul_coverage.sh +++ b/scripts/yul_coverage.sh @@ -83,7 +83,8 @@ for arg in "$@"; do esac done -show_output_if() { +function show_output_if +{ local VAR=${1} if [ -n "${VAR}" ]; then echo "${SOL_FILE}" @@ -102,7 +103,8 @@ if [ ! -f "${SOLC}" ]; then exit 1 fi -test_file() { +function test_file +{ local SOL_FILE local OUTPUT SOL_FILE=${1} diff --git a/test/cmdlineTests.sh b/test/cmdlineTests.sh index 59c29ca45..2076eb993 100755 --- a/test/cmdlineTests.sh +++ b/test/cmdlineTests.sh @@ -154,7 +154,7 @@ function ask_expectation_update # General helper function for testing SOLC behaviour, based on file name, compile opts, exit code, stdout and stderr. # An failure is expected. -function test_solc_behaviour() +function test_solc_behaviour { local filename="${1}" local solc_args @@ -288,7 +288,7 @@ EOF } -function test_solc_assembly_output() +function test_solc_assembly_output { local input="${1}" local expected="${2}" diff --git a/test/docsCodeStyle.sh b/test/docsCodeStyle.sh index 33b787e25..675828d7e 100755 --- a/test/docsCodeStyle.sh +++ b/test/docsCodeStyle.sh @@ -10,11 +10,11 @@ REPO_ROOT=$(cd "$(dirname "$0")/.." && pwd) if [ "$CIRCLECI" ] then - function printTask() { echo "$(tput bold)$(tput setaf 2)$1$(tput setaf 7)"; } - function printError() { echo "$(tput setaf 1)$1$(tput setaf 7)"; } + function printTask { echo "$(tput bold)$(tput setaf 2)$1$(tput setaf 7)"; } + function printError { echo "$(tput setaf 1)$1$(tput setaf 7)"; } else - function printTask() { echo "$(tput bold)$(tput setaf 2)$1$(tput sgr0)"; } - function printError() { echo "$(tput setaf 1)$1$(tput sgr0)"; } + function printTask { echo "$(tput bold)$(tput setaf 2)$1$(tput sgr0)"; } + function printError { echo "$(tput setaf 1)$1$(tput sgr0)"; } fi printTask "Checking docs examples style" diff --git a/test/externalTests/common.sh b/test/externalTests/common.sh index f015b5fd7..4e28d233f 100644 --- a/test/externalTests/common.sh +++ b/test/externalTests/common.sh @@ -187,7 +187,8 @@ function run_test $test_fn } -function optimizer_settings_for_level { +function optimizer_settings_for_level +{ local level="$1" case "$level" in @@ -201,7 +202,8 @@ function optimizer_settings_for_level { esac } -function truffle_compiler_settings { +function truffle_compiler_settings +{ local solc_path="$1" local level="$2" local evm_version="$3" diff --git a/test/stopAfterParseTests.sh b/test/stopAfterParseTests.sh index a100146b0..503c43579 100755 --- a/test/stopAfterParseTests.sh +++ b/test/stopAfterParseTests.sh @@ -15,7 +15,7 @@ FILETMP=$(mktemp -d) cd "$FILETMP" || exit 1 -function testFile() +function testFile { set +e ALLOUTPUT=$($SOLC --combined-json ast --pretty-json "$@" --stop-after parsing 2>&1) From b57c0a0b81253b2bc484df8b9fd01847d1663cbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 25 Oct 2021 14:29:43 +0200 Subject: [PATCH 61/69] externalTests: Refactor to be more explicit and easier to adjust for special cases --- test/externalTests/colony.sh | 25 ++++++-- test/externalTests/common.sh | 90 +++++++++++---------------- test/externalTests/ens.sh | 23 +++++-- test/externalTests/gnosis-v2.sh | 22 +++++-- test/externalTests/gnosis.sh | 23 +++++-- test/externalTests/solc-js/solc-js.sh | 1 - test/externalTests/zeppelin.sh | 24 +++++-- 7 files changed, 125 insertions(+), 83 deletions(-) diff --git a/test/externalTests/colony.sh b/test/externalTests/colony.sh index ef06f1d7b..43b452ec4 100755 --- a/test/externalTests/colony.sh +++ b/test/externalTests/colony.sh @@ -27,24 +27,37 @@ source test/externalTests/common.sh verify_input "$1" SOLJSON="$1" -function install_fn { yarn; git submodule update --init; } function compile_fn { yarn run provision:token:contracts; } function test_fn { yarn run test:contracts; } function colony_test { - OPTIMIZER_LEVEL=3 - CONFIG="truffle.js" + local repo="https://github.com/solidity-external-tests/colonyNetwork.git" + local branch=develop_080 + local config_file="truffle.js" + local min_optimizer_level=3 + local max_optimizer_level=3 - truffle_setup "$SOLJSON" https://github.com/solidity-external-tests/colonyNetwork.git develop_080 - run_install "$SOLJSON" install_fn + setup_solcjs "$DIR" "$SOLJSON" + download_project "$repo" "$branch" "$DIR" + + replace_version_pragmas + force_truffle_solc_modules "$SOLJSON" + force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" + yarn + git submodule update --init cd lib rm -Rf dappsys git clone https://github.com/solidity-external-tests/dappsys-monolithic.git -b master_080 dappsys cd .. - truffle_run_test "$SOLJSON" compile_fn test_fn + replace_version_pragmas + force_truffle_solc_modules "$SOLJSON" + + for level in $(seq "$min_optimizer_level" "$max_optimizer_level"); do + truffle_run_test "$config_file" "${DIR}/solc" "$level" compile_fn test_fn + done } external_test ColonyNetworks colony_test diff --git a/test/externalTests/common.sh b/test/externalTests/common.sh index 4e28d233f..8f9b5d39e 100644 --- a/test/externalTests/common.sh +++ b/test/externalTests/common.sh @@ -22,6 +22,8 @@ set -e # Requires "${REPO_ROOT}/scripts/common.sh" to be included before. +CURRENT_EVM_VERSION=london + function verify_input { if [ ! -f "$1" ]; then @@ -51,8 +53,8 @@ function setup_solcjs { local dir="$1" local soljson="$2" - local branch="$3" - local path="$4" + local branch="${3:-master}" + local path="${4:-solc/}" cd "$dir" printLog "Setting up solc-js..." @@ -86,16 +88,6 @@ function force_truffle_version sed -i 's/"truffle":\s*".*"/"truffle": "'"$version"'"/g' package.json } -function truffle_setup -{ - local soljson="$1" - local repo="$2" - local branch="$3" - - setup_solcjs "$DIR" "$soljson" "master" "solc" - download_project "$repo" "$branch" "$DIR" -} - function replace_version_pragmas { # Replace fixed-version pragmas (part of Consensys best practice). @@ -131,7 +123,7 @@ function force_truffle_compiler_settings local config_file="$1" local solc_path="$2" local level="$3" - local evm_version="$4" + local evm_version="${4:-"$CURRENT_EVM_VERSION"}" printLog "Forcing Truffle compiler settings..." echo "-------------------------------------" @@ -147,30 +139,18 @@ function force_truffle_compiler_settings echo "module.exports['compilers'] = $(truffle_compiler_settings "$solc_path" "$level" "$evm_version");" >> "$config_file" } -function verify_compiler_version +function truffle_verify_compiler_version { local solc_version="$1" + local full_solc_version="$2" - printLog "Verify that the correct version ($solc_version) of the compiler was used to compile the contracts..." - grep -e "$solc_version" -r build/contracts > /dev/null + printLog "Verify that the correct version (${solc_version}/${full_solc_version}) of the compiler was used to compile the contracts..." + grep "$full_solc_version" --with-filename --recursive build/contracts || fail "Wrong compiler version detected." } -function clean +function truffle_clean { - rm -rf build || true -} - -function run_install -{ - local soljson="$1" - local init_fn="$2" - printLog "Running install function..." - - replace_version_pragmas - force_truffle_solc_modules "$soljson" - force_truffle_compiler_settings "$CONFIG" "${DIR}/solc" "$OPTIMIZER_LEVEL" london - - $init_fn + rm -rf build/ } function run_test @@ -219,31 +199,35 @@ function truffle_compiler_settings echo "}" } +function compile_and_run_test +{ + local compile_fn="$1" + local test_fn="$2" + local verify_fn="$3" + + printLog "Running compile function..." + $compile_fn + $verify_fn "$SOLCVERSION_SHORT" "$SOLCVERSION" + + if [[ "$COMPILE_ONLY" == 1 ]]; then + printLog "Skipping test function..." + else + printLog "Running test function..." + $test_fn + fi +} + function truffle_run_test { - local soljson="$1" - local compile_fn="$2" - local test_fn="$3" + local config_file="$1" + local solc_path="$2" + local optimizer_level="$3" + local compile_fn="$4" + local test_fn="$5" - replace_version_pragmas - force_truffle_solc_modules "$soljson" - - for level in $(seq "$OPTIMIZER_LEVEL" 3) - do - clean - force_truffle_compiler_settings "$CONFIG" "${DIR}/solc" "$level" london - - printLog "Running compile function..." - $compile_fn - verify_compiler_version "$SOLCVERSION" - - if [[ "$COMPILE_ONLY" == 1 ]]; then - printLog "Skipping test function..." - else - printLog "Running test function..." - $test_fn - fi - done + truffle_clean + force_truffle_compiler_settings "$config_file" "$solc_path" "$optimizer_level" + compile_and_run_test compile_fn test_fn truffle_verify_compiler_version } function external_test diff --git a/test/externalTests/ens.sh b/test/externalTests/ens.sh index e3bdb229a..f6a17d6a8 100755 --- a/test/externalTests/ens.sh +++ b/test/externalTests/ens.sh @@ -27,16 +27,19 @@ source test/externalTests/common.sh verify_input "$1" export SOLJSON="$1" -function install_fn { npm install; } function compile_fn { npx truffle compile; } function test_fn { npm run test; } function ens_test { - export OPTIMIZER_LEVEL=1 - export CONFIG="truffle-config.js" + local repo="https://github.com/ensdomains/ens.git" + local branch=master + local config_file="truffle-config.js" + local min_optimizer_level=1 + local max_optimizer_level=3 - truffle_setup "$SOLJSON" https://github.com/ensdomains/ens.git master + setup_solcjs "$DIR" "$SOLJSON" + download_project "$repo" "$branch" "$DIR" # Use latest Truffle. Older versions crash on the output from 0.8.0. force_truffle_version ^5.1.55 @@ -44,9 +47,17 @@ function ens_test # Remove the lock file (if it exists) to prevent it from overriding our changes in package.json rm -f package-lock.json - run_install "$SOLJSON" install_fn + replace_version_pragmas + force_truffle_solc_modules "$SOLJSON" + force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" + npm install - truffle_run_test "$SOLJSON" compile_fn test_fn + replace_version_pragmas + force_truffle_solc_modules "$SOLJSON" + + for level in $(seq "$min_optimizer_level" "$max_optimizer_level"); do + truffle_run_test "$config_file" "${DIR}/solc" "$level" compile_fn test_fn + done } external_test Ens ens_test diff --git a/test/externalTests/gnosis-v2.sh b/test/externalTests/gnosis-v2.sh index 338b2418f..f3aab6d34 100755 --- a/test/externalTests/gnosis-v2.sh +++ b/test/externalTests/gnosis-v2.sh @@ -33,10 +33,14 @@ function test_fn { npm test; } function gnosis_safe_test { - OPTIMIZER_LEVEL=2 - CONFIG="truffle-config.js" + local repo="https://github.com/solidity-external-tests/safe-contracts.git" + local branch=v2_080 + local config_file="truffle-config.js" + local min_optimizer_level=2 + local max_optimizer_level=3 - truffle_setup "$SOLJSON" https://github.com/solidity-external-tests/safe-contracts.git v2_080 + setup_solcjs "$DIR" "$SOLJSON" + download_project "$repo" "$branch" "$DIR" sed -i 's|github:gnosis/mock-contract#sol_0_5_0|github:solidity-external-tests/mock-contract#master_080|g' package.json sed -i -E 's|"@gnosis.pm/util-contracts": "[^"]+"|"@gnosis.pm/util-contracts": "github:solidity-external-tests/util-contracts#solc-7_080"|g' package.json @@ -44,9 +48,17 @@ function gnosis_safe_test # Remove the lock file (if it exists) to prevent it from overriding our changes in package.json rm -f package-lock.json - run_install "$SOLJSON" install_fn + replace_version_pragmas + force_truffle_solc_modules "$SOLJSON" + force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" + npm install --package-lock - truffle_run_test "$SOLJSON" compile_fn test_fn + replace_version_pragmas + force_truffle_solc_modules "$SOLJSON" + + for level in $(seq "$min_optimizer_level" "$max_optimizer_level"); do + truffle_run_test "$config_file" "${DIR}/solc" "$level" compile_fn test_fn + done } external_test Gnosis-Safe gnosis_safe_test diff --git a/test/externalTests/gnosis.sh b/test/externalTests/gnosis.sh index a8a50782d..7507a1b48 100755 --- a/test/externalTests/gnosis.sh +++ b/test/externalTests/gnosis.sh @@ -27,25 +27,36 @@ source test/externalTests/common.sh verify_input "$1" SOLJSON="$1" -function install_fn { npm install --package-lock; } function compile_fn { npx truffle compile; } function test_fn { npm test; } function gnosis_safe_test { - OPTIMIZER_LEVEL=2 - CONFIG="truffle-config.js" + local repo="https://github.com/solidity-external-tests/safe-contracts.git" + local branch=development_080 + local config_file="truffle-config.js" + local min_optimizer_level=2 + local max_optimizer_level=3 - truffle_setup "$SOLJSON" https://github.com/solidity-external-tests/safe-contracts.git development_080 + setup_solcjs "$DIR" "$SOLJSON" + download_project "$repo" "$branch" "$DIR" sed -i 's|github:gnosis/mock-contract#sol_0_5_0|github:solidity-external-tests/mock-contract#master_080|g' package.json # Remove the lock file (if it exists) to prevent it from overriding our changes in package.json rm -f package-lock.json - run_install "$SOLJSON" install_fn + replace_version_pragmas + force_truffle_solc_modules "$SOLJSON" + force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" + npm install --package-lock - truffle_run_test "$SOLJSON" compile_fn test_fn + replace_version_pragmas + force_truffle_solc_modules "$SOLJSON" + + for level in $(seq "$min_optimizer_level" "$max_optimizer_level"); do + truffle_run_test "$config_file" "${DIR}/solc" "$level" compile_fn test_fn + done } external_test Gnosis-Safe gnosis_safe_test diff --git a/test/externalTests/solc-js/solc-js.sh b/test/externalTests/solc-js/solc-js.sh index fa0d7ccee..a3b24db9e 100755 --- a/test/externalTests/solc-js/solc-js.sh +++ b/test/externalTests/solc-js/solc-js.sh @@ -28,7 +28,6 @@ verify_version_input "$1" "$2" SOLJSON="$1" VERSION="$2" -function install_fn { echo "Nothing to install."; } function compile_fn { echo "Nothing to compile."; } function test_fn { npm test; } diff --git a/test/externalTests/zeppelin.sh b/test/externalTests/zeppelin.sh index ca90d46f4..f665c9d62 100755 --- a/test/externalTests/zeppelin.sh +++ b/test/externalTests/zeppelin.sh @@ -27,19 +27,31 @@ source test/externalTests/common.sh verify_input "$1" SOLJSON="$1" -function install_fn { npm install; } function compile_fn { npx truffle compile; } function test_fn { npm run test; } function zeppelin_test { - OPTIMIZER_LEVEL=1 - CONFIG="truffle-config.js" + local repo="https://github.com/OpenZeppelin/openzeppelin-contracts.git" + local branch=master + local config_file="truffle-config.js" + local min_optimizer_level=1 + local max_optimizer_level=3 - truffle_setup "$SOLJSON" https://github.com/OpenZeppelin/openzeppelin-contracts.git master - run_install "$SOLJSON" install_fn + setup_solcjs "$DIR" "$SOLJSON" + download_project "$repo" "$branch" "$DIR" - truffle_run_test "$SOLJSON" compile_fn test_fn + replace_version_pragmas + force_truffle_solc_modules "$SOLJSON" + force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" + npm install + + replace_version_pragmas + force_truffle_solc_modules "$SOLJSON" + + for level in $(seq "$min_optimizer_level" "$max_optimizer_level"); do + truffle_run_test "$config_file" "${DIR}/solc" "$level" compile_fn test_fn + done } external_test Zeppelin zeppelin_test From 7b7cc081db7d252dbe6a805c304219cfe399c0e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 26 Oct 2021 15:00:34 +0200 Subject: [PATCH 62/69] externalTests: Helper for neutralizing package locks --- test/externalTests/common.sh | 8 ++++++++ test/externalTests/ens.sh | 4 +--- test/externalTests/gnosis-v2.sh | 4 +--- test/externalTests/gnosis.sh | 4 +--- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/test/externalTests/common.sh b/test/externalTests/common.sh index 8f9b5d39e..038036159 100644 --- a/test/externalTests/common.sh +++ b/test/externalTests/common.sh @@ -96,6 +96,14 @@ function replace_version_pragmas find . test -name '*.sol' -type f -print0 | xargs -0 sed -i -E -e 's/pragma solidity [^;]+;/pragma solidity >=0.0;/' } +function neutralize_package_lock +{ + # Remove lock files (if they exist) to prevent them from overriding our changes in package.json + printLog "Removing package lock files..." + rm --force --verbose yarn.lock + rm --force --verbose package-lock.json +} + function force_truffle_solc_modules { local soljson="$1" diff --git a/test/externalTests/ens.sh b/test/externalTests/ens.sh index f6a17d6a8..de49e1ee3 100755 --- a/test/externalTests/ens.sh +++ b/test/externalTests/ens.sh @@ -44,9 +44,7 @@ function ens_test # Use latest Truffle. Older versions crash on the output from 0.8.0. force_truffle_version ^5.1.55 - # Remove the lock file (if it exists) to prevent it from overriding our changes in package.json - rm -f package-lock.json - + neutralize_package_lock replace_version_pragmas force_truffle_solc_modules "$SOLJSON" force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" diff --git a/test/externalTests/gnosis-v2.sh b/test/externalTests/gnosis-v2.sh index f3aab6d34..6e9c5e02b 100755 --- a/test/externalTests/gnosis-v2.sh +++ b/test/externalTests/gnosis-v2.sh @@ -45,9 +45,7 @@ function gnosis_safe_test sed -i 's|github:gnosis/mock-contract#sol_0_5_0|github:solidity-external-tests/mock-contract#master_080|g' package.json sed -i -E 's|"@gnosis.pm/util-contracts": "[^"]+"|"@gnosis.pm/util-contracts": "github:solidity-external-tests/util-contracts#solc-7_080"|g' package.json - # Remove the lock file (if it exists) to prevent it from overriding our changes in package.json - rm -f package-lock.json - + neutralize_package_lock replace_version_pragmas force_truffle_solc_modules "$SOLJSON" force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" diff --git a/test/externalTests/gnosis.sh b/test/externalTests/gnosis.sh index 7507a1b48..5730b3495 100755 --- a/test/externalTests/gnosis.sh +++ b/test/externalTests/gnosis.sh @@ -43,9 +43,7 @@ function gnosis_safe_test sed -i 's|github:gnosis/mock-contract#sol_0_5_0|github:solidity-external-tests/mock-contract#master_080|g' package.json - # Remove the lock file (if it exists) to prevent it from overriding our changes in package.json - rm -f package-lock.json - + neutralize_package_lock replace_version_pragmas force_truffle_solc_modules "$SOLJSON" force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" From c090ff9d833a113113af8db75f174daddae7c281 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 26 Oct 2021 15:39:19 +0200 Subject: [PATCH 63/69] externalTests: Neutralize npm hooks instead of replacing pragmas twice - This also has the nice effect of stopping projects from trying to compile contracts during installation --- test/externalTests/colony.sh | 3 +-- test/externalTests/common.sh | 8 ++++++++ test/externalTests/ens.sh | 3 +-- test/externalTests/gnosis-v2.sh | 3 +-- test/externalTests/gnosis.sh | 3 +-- test/externalTests/zeppelin.sh | 3 +-- 6 files changed, 13 insertions(+), 10 deletions(-) diff --git a/test/externalTests/colony.sh b/test/externalTests/colony.sh index 43b452ec4..33526f58e 100755 --- a/test/externalTests/colony.sh +++ b/test/externalTests/colony.sh @@ -41,8 +41,7 @@ function colony_test setup_solcjs "$DIR" "$SOLJSON" download_project "$repo" "$branch" "$DIR" - replace_version_pragmas - force_truffle_solc_modules "$SOLJSON" + neutralize_package_json_hooks force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" yarn git submodule update --init diff --git a/test/externalTests/common.sh b/test/externalTests/common.sh index 038036159..cee846a5b 100644 --- a/test/externalTests/common.sh +++ b/test/externalTests/common.sh @@ -104,6 +104,14 @@ function neutralize_package_lock rm --force --verbose package-lock.json } +function neutralize_package_json_hooks +{ + printLog "Disabling package.json hooks..." + [[ -f package.json ]] || fail "package.json not found" + sed -i 's|"prepublish": *".*"|"prepublish": ""|g' package.json + sed -i 's|"prepare": *".*"|"prepare": ""|g' package.json +} + function force_truffle_solc_modules { local soljson="$1" diff --git a/test/externalTests/ens.sh b/test/externalTests/ens.sh index de49e1ee3..5ec630658 100755 --- a/test/externalTests/ens.sh +++ b/test/externalTests/ens.sh @@ -45,8 +45,7 @@ function ens_test force_truffle_version ^5.1.55 neutralize_package_lock - replace_version_pragmas - force_truffle_solc_modules "$SOLJSON" + neutralize_package_json_hooks force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" npm install diff --git a/test/externalTests/gnosis-v2.sh b/test/externalTests/gnosis-v2.sh index 6e9c5e02b..e8593aa61 100755 --- a/test/externalTests/gnosis-v2.sh +++ b/test/externalTests/gnosis-v2.sh @@ -46,8 +46,7 @@ function gnosis_safe_test sed -i -E 's|"@gnosis.pm/util-contracts": "[^"]+"|"@gnosis.pm/util-contracts": "github:solidity-external-tests/util-contracts#solc-7_080"|g' package.json neutralize_package_lock - replace_version_pragmas - force_truffle_solc_modules "$SOLJSON" + neutralize_package_json_hooks force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" npm install --package-lock diff --git a/test/externalTests/gnosis.sh b/test/externalTests/gnosis.sh index 5730b3495..95a1ecd49 100755 --- a/test/externalTests/gnosis.sh +++ b/test/externalTests/gnosis.sh @@ -44,8 +44,7 @@ function gnosis_safe_test sed -i 's|github:gnosis/mock-contract#sol_0_5_0|github:solidity-external-tests/mock-contract#master_080|g' package.json neutralize_package_lock - replace_version_pragmas - force_truffle_solc_modules "$SOLJSON" + neutralize_package_json_hooks force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" npm install --package-lock diff --git a/test/externalTests/zeppelin.sh b/test/externalTests/zeppelin.sh index f665c9d62..750be3229 100755 --- a/test/externalTests/zeppelin.sh +++ b/test/externalTests/zeppelin.sh @@ -41,8 +41,7 @@ function zeppelin_test setup_solcjs "$DIR" "$SOLJSON" download_project "$repo" "$branch" "$DIR" - replace_version_pragmas - force_truffle_solc_modules "$SOLJSON" + neutralize_package_json_hooks force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" npm install From 0745279f1562d1d7efb2707c74d046f129c74c4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 27 Oct 2021 16:26:52 +0200 Subject: [PATCH 64/69] externalTests: Generalize force_truffle_solc_modules and make it use symlinks instead of redownloading solc-js --- test/externalTests/colony.sh | 2 +- test/externalTests/common.sh | 27 ++++++++++++--------------- test/externalTests/ens.sh | 2 +- test/externalTests/gnosis-v2.sh | 2 +- test/externalTests/gnosis.sh | 2 +- test/externalTests/zeppelin.sh | 2 +- 6 files changed, 17 insertions(+), 20 deletions(-) diff --git a/test/externalTests/colony.sh b/test/externalTests/colony.sh index 33526f58e..e32385af6 100755 --- a/test/externalTests/colony.sh +++ b/test/externalTests/colony.sh @@ -52,7 +52,7 @@ function colony_test cd .. replace_version_pragmas - force_truffle_solc_modules "$SOLJSON" + force_solc_modules "${DIR}/solc" for level in $(seq "$min_optimizer_level" "$max_optimizer_level"); do truffle_run_test "$config_file" "${DIR}/solc" "$level" compile_fn test_fn diff --git a/test/externalTests/common.sh b/test/externalTests/common.sh index cee846a5b..dbda3c3f4 100644 --- a/test/externalTests/common.sh +++ b/test/externalTests/common.sh @@ -112,25 +112,22 @@ function neutralize_package_json_hooks sed -i 's|"prepare": *".*"|"prepare": ""|g' package.json } -function force_truffle_solc_modules +function force_solc_modules { - local soljson="$1" + local custom_solcjs_path="${1:-solc/}" - # Replace solc package by v0.5.0 and then overwrite with current version. - printLog "Forcing solc version for all Truffle modules..." - for d in node_modules node_modules/truffle/node_modules + [[ -d node_modules/ ]] || assertFail + + printLog "Replacing all installed solc-js with a link to the latest version..." + soljson_binaries=$(find node_modules -type f -path "*/solc/soljson.js") + for soljson_binary in $soljson_binaries do - ( - if [ -d "$d" ]; then - cd $d - rm -rf solc - git clone --depth 1 -b master https://github.com/ethereum/solc-js.git solc - cp "$soljson" solc/soljson.js + local solc_module_path + solc_module_path=$(dirname "$soljson_binary") - cd solc - npm install - fi - ) + printLog "Found and replaced solc-js in $solc_module_path" + rm -r "$solc_module_path" + ln -s "$custom_solcjs_path" "$solc_module_path" done } diff --git a/test/externalTests/ens.sh b/test/externalTests/ens.sh index 5ec630658..bbdc573e2 100755 --- a/test/externalTests/ens.sh +++ b/test/externalTests/ens.sh @@ -50,7 +50,7 @@ function ens_test npm install replace_version_pragmas - force_truffle_solc_modules "$SOLJSON" + force_solc_modules "${DIR}/solc" for level in $(seq "$min_optimizer_level" "$max_optimizer_level"); do truffle_run_test "$config_file" "${DIR}/solc" "$level" compile_fn test_fn diff --git a/test/externalTests/gnosis-v2.sh b/test/externalTests/gnosis-v2.sh index e8593aa61..d92bcc186 100755 --- a/test/externalTests/gnosis-v2.sh +++ b/test/externalTests/gnosis-v2.sh @@ -51,7 +51,7 @@ function gnosis_safe_test npm install --package-lock replace_version_pragmas - force_truffle_solc_modules "$SOLJSON" + force_solc_modules "${DIR}/solc" for level in $(seq "$min_optimizer_level" "$max_optimizer_level"); do truffle_run_test "$config_file" "${DIR}/solc" "$level" compile_fn test_fn diff --git a/test/externalTests/gnosis.sh b/test/externalTests/gnosis.sh index 95a1ecd49..b6d9ab0bc 100755 --- a/test/externalTests/gnosis.sh +++ b/test/externalTests/gnosis.sh @@ -49,7 +49,7 @@ function gnosis_safe_test npm install --package-lock replace_version_pragmas - force_truffle_solc_modules "$SOLJSON" + force_solc_modules "${DIR}/solc" for level in $(seq "$min_optimizer_level" "$max_optimizer_level"); do truffle_run_test "$config_file" "${DIR}/solc" "$level" compile_fn test_fn diff --git a/test/externalTests/zeppelin.sh b/test/externalTests/zeppelin.sh index 750be3229..1e23bb7ae 100755 --- a/test/externalTests/zeppelin.sh +++ b/test/externalTests/zeppelin.sh @@ -46,7 +46,7 @@ function zeppelin_test npm install replace_version_pragmas - force_truffle_solc_modules "$SOLJSON" + force_solc_modules "${DIR}/solc" for level in $(seq "$min_optimizer_level" "$max_optimizer_level"); do truffle_run_test "$config_file" "${DIR}/solc" "$level" compile_fn test_fn From df85d2640652060ba967c8e4ba00d8116cb1a447 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 8 Nov 2021 15:56:09 +0100 Subject: [PATCH 65/69] Update ir-breaking-changes and make it visible. --- docs/conf.py | 2 +- docs/index.rst | 1 + docs/{ir => }/ir-breaking-changes.rst | 54 ++++++++++++++++++++++----- 3 files changed, 46 insertions(+), 11 deletions(-) rename docs/{ir => }/ir-breaking-changes.rst (82%) diff --git a/docs/conf.py b/docs/conf.py index b75eb966d..5fa2e6ab5 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -91,7 +91,7 @@ else: # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns = ['_build', 'contracts', 'types', 'examples', 'grammar', 'ir'] +exclude_patterns = ['_build', 'contracts', 'types', 'examples', 'grammar'] # The reST default role (used for this markup: `text`) to use for all # documents. diff --git a/docs/index.rst b/docs/index.rst index 476cd8611..60b3d61fa 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -136,6 +136,7 @@ Contents using-the-compiler.rst analysing-compilation-output.rst + ir-breaking-changes.rst .. toctree:: :maxdepth: 2 diff --git a/docs/ir/ir-breaking-changes.rst b/docs/ir-breaking-changes.rst similarity index 82% rename from docs/ir/ir-breaking-changes.rst rename to docs/ir-breaking-changes.rst index fb971410a..c1f6deb57 100644 --- a/docs/ir/ir-breaking-changes.rst +++ b/docs/ir-breaking-changes.rst @@ -5,8 +5,26 @@ Solidity IR-based Codegen Changes ********************************* -This section highlights the main differences between the old and the IR-based codegen, -along with the reasoning behind the changes and how to update affected code. +Solidity can generate EVM bytecode in two different ways: +Either directly from Solidity to EVM opcodes ("old codegen") or through +an intermediate representation ("IR") in Yul ("new codegen" or "IR-based codegen"). + +The IR-based code generator was introduced with an aim to not only allow +code generation to be more transparent and auditable but also +to enable more powerful optimization passes that span across functions. + +Currently, the IR-based code generator is still marked experimental, +but it supports all language features and has received a lot of testing, +so we consider it almost ready for production use. + +You can enable it on the command line using ``--experimental-via-ir`` +or with the option ``{"viaIR": true}`` in standard-json and we +encourage everyone to try it out! + +For several reasons, there are tiny semantic differences between the old +and the IR-based code generator, mostly in areas where we would not +expect people to rely on this behaviour anyway. +This section highlights the main differences between the old and the IR-based codegen. Semantic Only Changes ===================== @@ -14,8 +32,13 @@ Semantic Only Changes This section lists the changes that are semantic-only, thus potentially hiding new and different behavior in existing code. -- When storage structs are deleted, every storage slot that contains a member of the struct is set to zero entirely. Formally, padding space was left untouched. - Consequently, if the padding space within a struct is used to store data (e.g. in the context of a contract upgrade), you have to be aware that ``delete`` will now also clear the added member (while it wouldn't have been cleared in the past). +- When storage structs are deleted, every storage slot that contains + a member of the struct is set to zero entirely. Formerly, padding space + was left untouched. + Consequently, if the padding space within a struct is used to store data + (e.g. in the context of a contract upgrade), you have to be aware that + ``delete`` will now also clear the added member (while it wouldn't + have been cleared in the past). .. code-block:: solidity @@ -132,7 +155,10 @@ This causes differences in some contracts, for example: 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. 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. -- Copying ``bytes`` arrays from memory to storage is implemented in a different way. The old code generator always copies full words, while the new one cuts the byte array after its end. The old behaviour can lead to dirty data being copied after the end of the array (but still in the same storage slot). +- Copying ``bytes`` arrays from memory to storage is implemented in a different way. + The old code generator always copies full words, while the new one cuts the byte + array after its end. The old behaviour can lead to dirty data being copied after + the end of the array (but still in the same storage slot). This causes differences in some contracts, for example: .. code-block:: solidity @@ -155,8 +181,10 @@ This causes differences in some contracts, for example: } } - Previously ``f()`` would return ``0x6465616462656566313564656164000000000000000000000000000000000010`` (it has correct length, and correct first 8 elements, but then it contains dirty data which was set via assembly). - Now it is returning ``0x6465616462656566000000000000000000000000000000000000000000000010`` (it has correct length, and correct elements, but does not contain superfluous data). + Previously ``f()`` would return ``0x6465616462656566313564656164000000000000000000000000000000000010`` + (it has correct length, and correct first 8 elements, but then it contains dirty data which was set via assembly). + Now it is returning ``0x6465616462656566000000000000000000000000000000000000000000000010`` (it has + correct length, and correct elements, but does not contain superfluous data). .. index:: ! evaluation order; expression @@ -183,7 +211,8 @@ This causes differences in some contracts, for example: .. index:: ! evaluation order; function arguments - On the other hand, function argument expressions are evaluated in the same order by both code generators with the exception of the global functions ``addmod`` and ``mulmod``. + On the other hand, function argument expressions are evaluated in the same order + by both code generators with the exception of the global functions ``addmod`` and ``mulmod``. For example: .. code-block:: solidity @@ -227,11 +256,15 @@ This causes differences in some contracts, for example: - Old code generator: ``aMod = 0`` and ``mMod = 2`` - New code generator: ``aMod = 4`` and ``mMod = 0`` -- The new code generator imposes a hard limit of ``type(uint64).max`` (``0xffffffffffffffff``) for the free memory pointer. Allocations that would increase its value beyond this limit revert. The old code generator does not have this limit. +- The new code generator imposes a hard limit of ``type(uint64).max`` + (``0xffffffffffffffff``) for the free memory pointer. Allocations that would + increase its value beyond this limit revert. The old code generator does not + have this limit. For example: .. code-block:: solidity + :force: // SPDX-License-Identifier: GPL-3.0 pragma solidity >0.8.0; @@ -264,7 +297,7 @@ The old code generator uses code offsets or tags for values of internal function these offsets are different at construction time and after deployment and the values can cross this border via storage. Because of that, both offsets are encoded at construction time into the same value (into different bytes). -In the new code generator, function pointers use the AST IDs of the functions as values. Since calls via jumps are not possible, +In the new code generator, function pointers use internal IDs that are allocated in sequence. Since calls via jumps are not possible, calls through function pointers always have to use an internal dispatch function that uses the ``switch`` statement to select the right function. @@ -280,6 +313,7 @@ Cleanup The old code generator only performs cleanup before an operation whose result could be affected by the values of the dirty bits. The new code generator performs cleanup after any operation that can result in dirty bits. +The hope is that the optimizer will be powerful enough to eliminate redundant cleanup operations. For example: From 45c9dbe1743c0e5cd5a3f42a97ce7afda977ff5a Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 8 Nov 2021 13:06:20 +0100 Subject: [PATCH 66/69] Sort changelog and set release date. --- Changelog.md | 12 ++++++------ docs/bugs_by_version.json | 4 ++++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Changelog.md b/Changelog.md index 174c59356..ee463b25c 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,4 +1,4 @@ -### 0.8.10 (unreleased) +### 0.8.10 (2021-11-09) Language Features: * Inline Assembly: Support ``.address`` and ``.selector`` on external function pointers to access their address and function selector. @@ -28,23 +28,23 @@ Bugfixes: * 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. * SMTChecker: Fix internal error in magic type access (``block``, ``msg``, ``tx``). * SMTChecker: Fix internal error in the CHC engine when passing gas in the function options. - * TypeChecker: Fix internal error when using user defined value types in public library functions. * TypeChecker: Fix internal error when using arrays and structs with user defined value types before declaration. + * TypeChecker: Fix internal error when using user defined value types in public library functions. * TypeChecker: Improved error message for constant variables with (nested) mapping types. * Yul Assembler: Fix internal error when function names are not unique. * Yul IR Generator: Do not output empty switches/if-bodies for empty contracts. +Important Bugfixes in Experimental Features: + * 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. + + Build System: * Pass linker-only emscripten options only when linking. * Remove obsolete compatibility workaround for emscripten builds. * Update emscripten to version 2.0.33. -Important Bugfixes in Experimental Features: - * 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. - - ### 0.8.9 (2021-09-29) Important Bugfixes: diff --git a/docs/bugs_by_version.json b/docs/bugs_by_version.json index 4324b8339..6385af170 100644 --- a/docs/bugs_by_version.json +++ b/docs/bugs_by_version.json @@ -1544,6 +1544,10 @@ ], "released": "2021-01-27" }, + "0.8.10": { + "bugs": [], + "released": "2021-11-09" + }, "0.8.2": { "bugs": [ "SignedImmutables", From 75fd7fa93e1059aed362093191feb3e27804d465 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 21 Oct 2021 18:40:55 +0200 Subject: [PATCH 67/69] CI: Modify notification steps to be silent in PRs --- .circleci/config.yml | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9e5862cab..b7d501c71 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -31,7 +31,7 @@ orbs: win: circleci/windows@2.2.0 commands: - gitter_notify: + gitter_notify_unless_pr: description: "Posts a notification to the main room on Gitter (if not running on a PR)." parameters: event: @@ -44,6 +44,8 @@ commands: name: "Gitter notification" when: << parameters.condition >> command: | + [[ $CI_PULL_REQUEST == "" ]] || { echo "Running on a PR - notification skipped."; exit 0; } + [[ "<< parameters.event >>" == "failure" ]] && message=" ❌ Nightly job **${CIRCLE_JOB}** failed on **${CIRCLE_BRANCH}**. Please see [build #${CIRCLE_BUILD_NUM}](${CIRCLE_BUILD_URL}) for details." [[ "<< parameters.event >>" == "success" ]] && message=" ✅ Nightly job **${CIRCLE_JOB}** succeeded on **${CIRCLE_BRANCH}**. Please see [build #${CIRCLE_BUILD_NUM}](${CIRCLE_BUILD_URL}) for details." @@ -55,17 +57,17 @@ commands: --header "Authorization: Bearer ${GITTER_API_TOKEN}" \ --data "{\"text\":\"${message}\"}" - gitter_notify_failure: + gitter_notify_failure_unless_pr: description: "Posts a failure notification to the main room on Gitter (if not running on a PR)." steps: - - gitter_notify: + - gitter_notify_unless_pr: event: failure condition: on_fail - gitter_notify_success: + gitter_notify_success_unless_pr: description: "Posts a success notification to the main room on Gitter (if not running on a PR)." steps: - - gitter_notify: + - gitter_notify_unless_pr: event: success condition: on_success @@ -562,9 +564,9 @@ jobs: steps: - checkout - run: *run_build - - gitter_notify_failure - store_artifacts: *artifacts_solc - persist_to_workspace: *artifacts_executables + - gitter_notify_failure_unless_pr b_ubu_release: &b_ubu_release <<: *b_ubu @@ -650,10 +652,10 @@ jobs: git clone https://github.com/ethereum/solidity-fuzzing-corpus /tmp/solidity-fuzzing-corpus mkdir -p test_results scripts/regressions.py -o test_results - - gitter_notify_failure - - gitter_notify_success - store_test_results: *store_test_results - store_artifacts: *artifacts_test_results + - gitter_notify_failure_unless_pr + - gitter_notify_success_unless_pr b_archlinux: <<: *base_archlinux @@ -852,7 +854,7 @@ jobs: - when: condition: true <<: *steps_soltest - - gitter_notify_failure + - gitter_notify_failure_unless_pr t_ubu_ubsan_clang_cli: <<: *base_ubuntu2004_clang @@ -860,7 +862,7 @@ jobs: - when: condition: true <<: *steps_cmdline_tests - - gitter_notify_failure + - gitter_notify_failure_unless_pr t_ems_solcjs: <<: *base_ubuntu2004 @@ -940,8 +942,8 @@ jobs: - when: condition: <> steps: - - gitter_notify_failure - - gitter_notify_success + - gitter_notify_failure_unless_pr + - gitter_notify_success_unless_pr b_win: &b_win <<: *base_win_powershell From 205e05b8f12cdd754adea2850055751fb201709b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 21 Oct 2021 18:46:04 +0200 Subject: [PATCH 68/69] CI: Add gitter failure notifications to all jobs --- .circleci/config.yml | 60 ++++++++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 19 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b7d501c71..72434ea15 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -189,6 +189,7 @@ defaults: - run: *run_soltest - store_test_results: *store_test_results - store_artifacts: *artifacts_test_results + - gitter_notify_failure_unless_pr - steps_soltest_all: &steps_soltest_all steps: @@ -198,6 +199,7 @@ defaults: - run: *run_soltest_all - store_test_results: *store_test_results - store_artifacts: *artifacts_test_results + - gitter_notify_failure_unless_pr - steps_cmdline_tests: &steps_cmdline_tests steps: @@ -207,6 +209,7 @@ defaults: - run: *run_cmdline_tests - store_test_results: *store_test_results - store_artifacts: *artifacts_test_results + - gitter_notify_failure_unless_pr # -------------------------------------------------------------------------- # Base Image Templates @@ -396,6 +399,7 @@ jobs: - run: name: Check spelling command: ~/.local/bin/codespell -S "*.enc,.git,Dockerfile*" -I ./scripts/codespell_whitelist.txt + - gitter_notify_failure_unless_pr chk_docs_examples: <<: *base_node_latest @@ -409,6 +413,7 @@ jobs: - run: name: Test Docs examples command: ./test/docsCodeStyle.sh + - gitter_notify_failure_unless_pr chk_coding_style: <<: *base_buildpack_focal @@ -426,6 +431,7 @@ jobs: - run: name: Check for broken symlinks command: ./scripts/check_symlinks.sh + - gitter_notify_failure_unless_pr chk_errorcodes: <<: *base_python @@ -434,6 +440,7 @@ jobs: - run: name: Check for error codes command: ./scripts/error_codes.py --check + - gitter_notify_failure_unless_pr chk_pylint: <<: *base_buildpack_focal @@ -449,6 +456,7 @@ jobs: - run: name: Linting Python Scripts command: ./scripts/pylint_all.py + - gitter_notify_failure_unless_pr chk_antlr_grammar: <<: *base_buildpack_focal @@ -460,6 +468,7 @@ jobs: - run: name: Run tests command: ./scripts/test_antlr_grammar.sh + - gitter_notify_failure_unless_pr chk_buglist: <<: *base_node_latest @@ -474,6 +483,7 @@ jobs: - run: name: Test buglist command: ./test/buglistTests.js + - gitter_notify_failure_unless_pr chk_proofs: <<: *base_buildpack_latest @@ -486,12 +496,14 @@ jobs: apt-get -qy install python3-pip pip3 install --user z3-solver - run: *run_proofs + - gitter_notify_failure_unless_pr chk_docs_pragma_min_version: <<: *base_ubuntu2004 steps: - checkout - run: *run_docs_pragma_min_version + - gitter_notify_failure_unless_pr t_ubu_pyscripts: <<: *base_ubuntu2004 @@ -500,6 +512,7 @@ jobs: - run: name: Python unit tests command: python3 test/pyscriptTests.py + - gitter_notify_failure_unless_pr t_win_pyscripts: <<: *base_win_powershell @@ -509,6 +522,7 @@ jobs: - run: name: Python unit tests command: python.exe test/pyscriptTests.py + - gitter_notify_failure_unless_pr b_ubu: &b_ubu <<: *base_ubuntu2004_xlarge @@ -519,6 +533,7 @@ jobs: - store_artifacts: *artifact_solidity_upgrade - store_artifacts: *artifact_yul_phaser - persist_to_workspace: *artifacts_executables + - gitter_notify_failure_unless_pr # x64 ASAN build, for testing for memory related bugs b_ubu_asan: &b_ubu_asan @@ -532,6 +547,7 @@ jobs: - run: *run_build - store_artifacts: *artifacts_solc - persist_to_workspace: *artifacts_executables + - gitter_notify_failure_unless_pr b_ubu_clang: &b_ubu_clang <<: *base_ubuntu2004_clang_xlarge @@ -540,6 +556,7 @@ jobs: - run: *run_build - store_artifacts: *artifacts_solc - persist_to_workspace: *artifacts_executables + - gitter_notify_failure_unless_pr b_ubu_asan_clang: &b_ubu_asan_clang <<: *base_ubuntu2004_clang @@ -553,6 +570,7 @@ jobs: - run: *run_build - store_artifacts: *artifacts_solc - persist_to_workspace: *artifacts_executables + - gitter_notify_failure_unless_pr b_ubu_ubsan_clang: &b_ubu_ubsan_clang <<: *base_ubuntu2004_clang @@ -586,6 +604,7 @@ jobs: name: strip binary command: strip build/solc/solc - store_artifacts: *artifacts_solc + - gitter_notify_failure_unless_pr b_ubu_codecov: <<: *base_ubuntu2004_xlarge @@ -597,6 +616,7 @@ jobs: - checkout - run: *run_build - persist_to_workspace: *artifacts_executables + - gitter_notify_failure_unless_pr t_ubu_codecov: <<: *base_ubuntu2004 @@ -619,6 +639,7 @@ jobs: name: "Coverage: All" command: codecov --flags all --gcov-root build - store_artifacts: *artifacts_test_results + - gitter_notify_failure_unless_pr # Builds in C++20 mode and uses debug build in order to speed up. # Do *NOT* store any artifacts or workspace as we don't run tests on this build. @@ -631,6 +652,7 @@ jobs: steps: - checkout - run: *run_build + - gitter_notify_failure_unless_pr b_ubu_ossfuzz: &b_ubu_ossfuzz <<: *base_ubuntu1604_clang @@ -639,6 +661,7 @@ jobs: - run: *setup_prerelease_commit_hash - run: *run_build_ossfuzz - persist_to_workspace: *artifacts_executables_ossfuzz + - gitter_notify_failure_unless_pr t_ubu_ossfuzz: &t_ubu_ossfuzz <<: *base_ubuntu1604_clang @@ -671,6 +694,7 @@ jobs: - run: *run_build - store_artifacts: *artifacts_solc - persist_to_workspace: *artifacts_executables + - gitter_notify_failure_unless_pr b_osx: <<: *base_osx @@ -707,6 +731,7 @@ jobs: - build/solc/solc - build/test/soltest - build/test/tools/solfuzzer + - gitter_notify_failure_unless_pr t_osx_soltest: <<: *base_osx @@ -724,6 +749,7 @@ jobs: - run: *run_soltest - store_test_results: *store_test_results - store_artifacts: *artifacts_test_results + - gitter_notify_failure_unless_pr t_osx_cli: <<: *base_osx @@ -736,6 +762,7 @@ jobs: at: . - run: *run_cmdline_tests - store_artifacts: *artifacts_test_results + - gitter_notify_failure_unless_pr b_ems: <<: *base_ems_xlarge @@ -756,6 +783,7 @@ jobs: paths: - soljson.js - version.txt + - gitter_notify_failure_unless_pr b_docs: <<: *base_ubuntu2004 @@ -768,6 +796,7 @@ jobs: - store_artifacts: path: docs/_build/html/ destination: docs-html + - gitter_notify_failure_unless_pr t_ubu_soltest_all: &t_ubu_soltest_all <<: *base_ubuntu2004 @@ -850,19 +879,11 @@ jobs: <<: *base_ubuntu2004_clang environment: EVM: << pipeline.parameters.evm-version >> - steps: - - when: - condition: true - <<: *steps_soltest - - gitter_notify_failure_unless_pr + <<: *steps_soltest t_ubu_ubsan_clang_cli: <<: *base_ubuntu2004_clang - steps: - - when: - condition: true - <<: *steps_cmdline_tests - - gitter_notify_failure_unless_pr + <<: *steps_cmdline_tests t_ems_solcjs: <<: *base_ubuntu2004 @@ -882,6 +903,7 @@ jobs: node --version npm --version test/externalTests/solc-js/solc-js.sh /tmp/workspace/soljson.js $(cat /tmp/workspace/version.txt) + - gitter_notify_failure_unless_pr t_ems_ext_hardhat: <<: *base_node_latest @@ -907,6 +929,7 @@ jobs: # NOTE: This is expected to work without running `yarn build` first. cd hardhat/packages/hardhat-core yarn test + - gitter_notify_failure_unless_pr t_ems_ext: parameters: @@ -918,9 +941,6 @@ jobs: nodejs_version: type: integer default: 14 - gitter_notify: - type: boolean - default: no docker: - image: circleci/node:<> environment: @@ -939,11 +959,7 @@ jobs: name: External <> tests command: | test/externalTests/<>.sh /tmp/workspace/soljson.js - - when: - condition: <> - steps: - - gitter_notify_failure_unless_pr - - gitter_notify_success_unless_pr + - gitter_notify_failure_unless_pr b_win: &b_win <<: *base_win_powershell @@ -974,6 +990,7 @@ jobs: paths: - .\solc\*\solc.exe - .\test\*\soltest.exe + - gitter_notify_failure_unless_pr b_win_release: <<: *b_win @@ -996,6 +1013,7 @@ jobs: command: .circleci/soltest.ps1 - store_test_results: *store_test_results - store_artifacts: *artifacts_test_results + - gitter_notify_failure_unless_pr t_win_release_soltest: <<: *t_win_soltest @@ -1019,6 +1037,7 @@ jobs: paths: - bytecode-report-ubuntu-json.txt - bytecode-report-ubuntu-cli.txt + - gitter_notify_failure_unless_pr b_bytecode_osx: <<: *base_osx @@ -1039,6 +1058,7 @@ jobs: paths: - bytecode-report-osx-json.txt - bytecode-report-osx-cli.txt + - gitter_notify_failure_unless_pr b_bytecode_win: <<: *base_win_cmd @@ -1062,6 +1082,7 @@ jobs: paths: - bytecode-report-windows-json.txt - bytecode-report-windows-cli.txt + - gitter_notify_failure_unless_pr b_bytecode_ems: <<: *base_node_latest @@ -1078,6 +1099,7 @@ jobs: root: . paths: - bytecode-report-emscripten.txt + - gitter_notify_failure_unless_pr t_bytecode_compare: <<: *base_ubuntu2004 @@ -1114,6 +1136,7 @@ jobs: # NOTE: store_artifacts does not support the 'when' attribute. # Fortunately when the artifact does not exist it just says "No artifact files found" and ignores it. path: all-bytecode-reports.zip + - gitter_notify_failure_unless_pr workflows: version: 2 @@ -1284,4 +1307,3 @@ workflows: <<: *workflow_emscripten name: t_ems_test_ext_colony project: colony - gitter_notify: yes From cffb7fec27c5f884a9a775738f7ab58a9d6d9275 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 9 Nov 2021 17:23:33 +0100 Subject: [PATCH 69/69] Set version to 0.8.11 --- CMakeLists.txt | 2 +- Changelog.md | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 23c2f0e42..e3dc030c1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,7 @@ include(EthPolicy) eth_policy() # project name and version should be set after cmake_policy CMP0048 -set(PROJECT_VERSION "0.8.10") +set(PROJECT_VERSION "0.8.11") # OSX target needed in order to support std::visit set(CMAKE_OSX_DEPLOYMENT_TARGET "10.14") project(solidity VERSION ${PROJECT_VERSION} LANGUAGES C CXX) diff --git a/Changelog.md b/Changelog.md index ee463b25c..79d5df058 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,14 @@ +### 0.8.11 (unreleased) + +Language Features: + + +Compiler Features: + + +Bugfixes: + + ### 0.8.10 (2021-11-09) Language Features: